57
57
} my_destination_mgr;
60
void rescaleImage( unsigned char *original_buffer, int width, int height, int byte_per_pixel, bool pad_flag, bool palette_flag )
60
void rescaleImage( unsigned char *original_buffer, int width, int height, int byte_per_pixel,
61
bool src_pad_flag, bool dst_pad_flag, bool palette_flag )
62
63
size_t width_pad = 0;
63
if ( pad_flag ) width_pad = (4 - width * byte_per_pixel % 4) % 4;
64
if ( src_pad_flag ) width_pad = (4 - width * byte_per_pixel % 4) % 4;
65
66
size_t w = (int)(width * scale_ratio_upper / scale_ratio_lower);
66
67
size_t h = (int)(height * scale_ratio_upper / scale_ratio_lower);
70
if ( pad_flag ) w_pad = (4 - w * byte_per_pixel % 4) % 4;
71
if ( dst_pad_flag ) w_pad = (4 - w * byte_per_pixel % 4) % 4;
72
73
if ( (w * byte_per_pixel + w_pad) * h > rescaled_tmp_length ){
73
74
int len = (w * byte_per_pixel + w_pad) * h;
141
size_t rescaleJPEG( unsigned char *original_buffer, size_t length, unsigned char **rescaled_buffer )
142
size_t rescaleJPEGWrite( unsigned int width, unsigned int height, int byte_per_pixel, unsigned char **rescaled_buffer,
143
int quality, bool bmp2jpeg_flag )
146
struct jpeg_compress_struct cinfo2;
147
JSAMPROW row_pointer[1];
149
cinfo2.err = jpeg_std_error(&jerr);
150
jpeg_create_compress(&cinfo2);
152
cinfo2.dest = (struct jpeg_destination_mgr *)
153
(*cinfo2.mem->alloc_small) ((j_common_ptr) &cinfo2, JPOOL_PERMANENT,
154
sizeof(my_destination_mgr));
155
my_destination_mgr * dest = (my_destination_mgr *) cinfo2.dest;
157
dest->buf = *rescaled_buffer;
158
dest->left = restored_length;
160
dest->pub.init_destination = init_destination;
161
dest->pub.empty_output_buffer = empty_output_buffer;
162
dest->pub.term_destination = term_destination;
164
cinfo2.image_width = (int)(width * scale_ratio_upper / scale_ratio_lower);
165
if ( cinfo2.image_width == 0 ) cinfo2.image_width = 1;
166
cinfo2.image_height = (int)(height * scale_ratio_upper / scale_ratio_lower);
167
if ( cinfo2.image_height == 0 ) cinfo2.image_height = 1;
168
cinfo2.input_components = byte_per_pixel;
169
if ( cinfo2.input_components == 1 )
170
cinfo2.in_color_space = JCS_GRAYSCALE;
172
cinfo2.in_color_space = JCS_RGB;
174
jpeg_set_defaults(&cinfo2);
175
jpeg_set_quality(&cinfo2, quality, TRUE );
176
cinfo2.optimize_coding = true;
177
//jpeg_simple_progression (&cinfo2);
178
jpeg_start_compress(&cinfo2, TRUE);
180
int row_stride = cinfo2.image_width * byte_per_pixel;
182
while (cinfo2.next_scanline < cinfo2.image_height) {
184
unsigned char *src = row_pointer[0] = &rescaled_tmp_buffer[(cinfo2.image_height - 1 - cinfo2.next_scanline) * row_stride];
185
for(unsigned int i=0 ; i<cinfo2.image_width ; i++, src+=3){
186
unsigned char tmp = src[2];
192
row_pointer[0] = &rescaled_tmp_buffer[cinfo2.next_scanline * row_stride];
194
jpeg_write_scanlines(&cinfo2, row_pointer, 1);
197
jpeg_finish_compress(&cinfo2);
198
size_t datacount = dest->left - dest->pub.free_in_buffer;
200
jpeg_destroy_compress(&cinfo2);
205
size_t rescaleJPEG( unsigned char *original_buffer, size_t length, unsigned char **rescaled_buffer, int quality )
143
207
struct jpeg_decompress_struct cinfo;
144
208
jpeg_error_mgr jerr;
185
249
buf_p += cinfo.output_width * cinfo.output_components;
188
rescaleImage( restored_buffer, cinfo.output_width, cinfo.output_height, cinfo.output_components, false, false );
190
/* ---------------------------------------- */
192
struct jpeg_compress_struct cinfo2;
193
JSAMPROW row_pointer[1];
195
cinfo2.err = jpeg_std_error(&jerr);
196
jpeg_create_compress(&cinfo2);
198
cinfo2.dest = (struct jpeg_destination_mgr *)
199
(*cinfo2.mem->alloc_small) ((j_common_ptr) &cinfo2, JPOOL_PERMANENT,
200
sizeof(my_destination_mgr));
201
my_destination_mgr * dest = (my_destination_mgr *) cinfo2.dest;
203
dest->buf = *rescaled_buffer;
204
dest->left = restored_length;
206
dest->pub.init_destination = init_destination;
207
dest->pub.empty_output_buffer = empty_output_buffer;
208
dest->pub.term_destination = term_destination;
210
cinfo2.image_width = (int)(cinfo.output_width * scale_ratio_upper / scale_ratio_lower);
211
if ( cinfo2.image_width == 0 ) cinfo2.image_width = 1;
212
cinfo2.image_height = (int)(cinfo.output_height * scale_ratio_upper / scale_ratio_lower);
213
if ( cinfo2.image_height == 0 ) cinfo2.image_height = 1;
214
cinfo2.input_components = cinfo.output_components;
215
if ( cinfo2.input_components == 1 )
216
cinfo2.in_color_space = JCS_GRAYSCALE;
218
cinfo2.in_color_space = JCS_RGB;
220
jpeg_set_defaults(&cinfo2);
221
jpeg_set_quality(&cinfo2, 75, TRUE );
222
jpeg_start_compress(&cinfo2, TRUE);
224
row_stride = cinfo2.image_width * cinfo.output_components;
226
while (cinfo2.next_scanline < cinfo2.image_height) {
227
row_pointer[0] = &rescaled_tmp_buffer[cinfo2.next_scanline * row_stride];
228
jpeg_write_scanlines(&cinfo2, row_pointer, 1);
231
jpeg_finish_compress(&cinfo2);
232
size_t datacount = dest->left - dest->pub.free_in_buffer;
252
rescaleImage( restored_buffer, cinfo.output_width, cinfo.output_height, cinfo.output_components, false, false, false );
254
size_t datacount = rescaleJPEGWrite(cinfo.output_width, cinfo.output_height, cinfo.output_components, rescaled_buffer, quality, false);
234
255
jpeg_destroy_decompress(&cinfo);
235
jpeg_destroy_compress(&cinfo2);
237
257
return datacount;
240
size_t rescaleBMP( unsigned char *original_buffer, size_t length, unsigned char **rescaled_buffer )
260
void rescaleBMPWrite( unsigned char *original_buffer, size_t total_size, int width, int height, unsigned char **rescaled_buffer )
262
int buffer_offset = original_buffer[10] + (original_buffer[11] << 8);
263
memcpy( *rescaled_buffer, original_buffer, buffer_offset );
264
memcpy( *rescaled_buffer + buffer_offset, rescaled_tmp_buffer, total_size - buffer_offset );
266
*(*rescaled_buffer + 2) = total_size & 0xff;
267
*(*rescaled_buffer + 3) = (total_size >> 8) & 0xff;
268
*(*rescaled_buffer + 4) = (total_size >> 16) & 0xff;
269
*(*rescaled_buffer + 5) = (total_size >> 24) & 0xff;
270
*(*rescaled_buffer + 18) = width & 0xff;
271
*(*rescaled_buffer + 19) = (width >> 8) & 0xff;
272
*(*rescaled_buffer + 20) = (width >> 16) & 0xff;
273
*(*rescaled_buffer + 21) = (width >> 24) & 0xff;
274
*(*rescaled_buffer + 22) = height & 0xff;
275
*(*rescaled_buffer + 23) = (height >> 8) & 0xff;
276
*(*rescaled_buffer + 24) = (height >> 16) & 0xff;
277
*(*rescaled_buffer + 25) = (height >> 24) & 0xff;
278
*(*rescaled_buffer + 34) = 0;
279
*(*rescaled_buffer + 35) = 0;
280
*(*rescaled_buffer + 36) = 0;
281
*(*rescaled_buffer + 37) = 0;
284
FILE *fp = fopen( "test.bmp", "wb" );
285
fwrite( *rescaled_buffer, 1, width2 * height2 * byte_per_pixel + 54 + color_num*4, fp );
291
size_t rescaleBMP( unsigned char *original_buffer, unsigned char **rescaled_buffer,
292
bool output_jpeg_flag, int quality )
242
294
if (original_buffer[14] != 40){
243
295
if (original_buffer[14] == 12)
270
323
size_t height2 = (int)(height * scale_ratio_upper / scale_ratio_lower);
271
324
if ( height2 == 0 ) height2 = 1;
273
rescaleImage( original_buffer+buffer_offset, width, height, byte_per_pixel, true, palette_flag );
275
326
size_t total_size = (width2 * byte_per_pixel + width2_pad) * height2 + buffer_offset;
276
if ( total_size > restored_length ){
277
restored_length = total_size;
327
if ( total_size+0x400 > restored_length ){
328
restored_length = total_size+0x400;
278
329
if ( restored_buffer ) delete[] restored_buffer;
279
330
restored_buffer = new unsigned char[ restored_length ];
280
331
if ( *rescaled_buffer ) delete[] *rescaled_buffer;
281
332
*rescaled_buffer = new unsigned char[ restored_length ];
284
memcpy( *rescaled_buffer, original_buffer, buffer_offset );
285
memcpy( *rescaled_buffer + buffer_offset, rescaled_tmp_buffer, total_size - buffer_offset );
287
*(*rescaled_buffer + 2) = total_size & 0xff;
288
*(*rescaled_buffer + 3) = (total_size >> 8) & 0xff;
289
*(*rescaled_buffer + 4) = (total_size >> 16) & 0xff;
290
*(*rescaled_buffer + 5) = (total_size >> 24) & 0xff;
291
*(*rescaled_buffer + 18) = width2 & 0xff;
292
*(*rescaled_buffer + 19) = (width2 >> 8) & 0xff;
293
*(*rescaled_buffer + 20) = (width2 >> 16) & 0xff;
294
*(*rescaled_buffer + 21) = (width2 >> 24) & 0xff;
295
*(*rescaled_buffer + 22) = height2 & 0xff;
296
*(*rescaled_buffer + 23) = (height2 >> 8) & 0xff;
297
*(*rescaled_buffer + 24) = (height2 >> 16) & 0xff;
298
*(*rescaled_buffer + 25) = (height2 >> 24) & 0xff;
299
*(*rescaled_buffer + 34) = 0;
300
*(*rescaled_buffer + 35) = 0;
301
*(*rescaled_buffer + 36) = 0;
302
*(*rescaled_buffer + 37) = 0;
305
FILE *fp = fopen( "test.bmp", "wb" );
306
fwrite( *rescaled_buffer, 1, width2 * height2 * byte_per_pixel + 54 + color_num*4, fp );
335
if (output_jpeg_flag){
336
rescaleImage( original_buffer+buffer_offset, width, height, byte_per_pixel, true, false, palette_flag );
337
total_size = rescaleJPEGWrite(width, height, byte_per_pixel, rescaled_buffer, quality, true);
340
rescaleImage( original_buffer+buffer_offset, width, height, byte_per_pixel, true, true, palette_flag );
341
rescaleBMPWrite(original_buffer, total_size, width2, height2, rescaled_buffer);
311
344
return total_size;