11 #define OUTBUFFER_SIZE 0x8000
14 static JOCTET
* buffer
;
15 static unsigned char*dest
;
18 static unsigned char*data
;
22 static void file_init_destination(j_compress_ptr cinfo
)
24 struct jpeg_destination_mgr
*dmgr
=
25 (struct jpeg_destination_mgr
*)(cinfo
->dest
);
26 buffer
= (JOCTET
*)malloc(OUTBUFFER_SIZE
);
29 printf("Out of memory!\n");
32 dmgr
->next_output_byte
= buffer
;
33 dmgr
->free_in_buffer
= OUTBUFFER_SIZE
;
36 static boolean
file_empty_output_buffer(j_compress_ptr cinfo
)
38 struct jpeg_destination_mgr
*dmgr
=
39 (struct jpeg_destination_mgr
*)(cinfo
->dest
);
41 fwrite(buffer
, OUTBUFFER_SIZE
, 1, fi
);
42 dmgr
->next_output_byte
= buffer
;
43 dmgr
->free_in_buffer
= OUTBUFFER_SIZE
;
47 static void file_term_destination(j_compress_ptr cinfo
)
48 { struct jpeg_destination_mgr
*dmgr
=
49 (struct jpeg_destination_mgr
*)(cinfo
->dest
);
51 fwrite(buffer
, OUTBUFFER_SIZE
-dmgr
->free_in_buffer
, 1, fi
);
54 dmgr
->free_in_buffer
= 0;
57 static void mem_init_destination(j_compress_ptr cinfo
)
59 struct jpeg_destination_mgr
*dmgr
=
60 (struct jpeg_destination_mgr
*)(cinfo
->dest
);
61 dmgr
->next_output_byte
= dest
;
62 dmgr
->free_in_buffer
= destlen
;
65 static boolean
mem_empty_output_buffer(j_compress_ptr cinfo
)
67 printf("jpeg mem overflow!\n");
71 static void mem_term_destination(j_compress_ptr cinfo
)
73 struct jpeg_destination_mgr
*dmgr
=
74 (struct jpeg_destination_mgr
*)(cinfo
->dest
);
75 len
= destlen
- dmgr
->free_in_buffer
;
76 dmgr
->free_in_buffer
= 0;
79 int jpeg_save(unsigned char*data
, unsigned width
, unsigned height
, int quality
, const char*filename
)
81 struct jpeg_destination_mgr mgr
;
82 struct jpeg_compress_struct cinfo
;
83 struct jpeg_error_mgr jerr
;
87 fi
= fopen(filename
, "wb");
91 memset(&cinfo
, 0, sizeof(cinfo
));
92 memset(&jerr
, 0, sizeof(jerr
));
93 memset(&mgr
, 0, sizeof(mgr
));
94 cinfo
.err
= jpeg_std_error(&jerr
);
95 jpeg_create_compress(&cinfo
);
97 mgr
.init_destination
= file_init_destination
;
98 mgr
.empty_output_buffer
= file_empty_output_buffer
;
99 mgr
.term_destination
= file_term_destination
;
104 cinfo
.image_width
= width
;
105 cinfo
.image_height
= height
;
106 cinfo
.input_components
= 3;
107 cinfo
.in_color_space
= JCS_RGB
;
108 jpeg_set_defaults(&cinfo
);
109 jpeg_set_quality(&cinfo
,quality
,TRUE
);
111 //jpeg_write_tables(&cinfo);
112 //jpeg_suppress_tables(&cinfo, TRUE);
113 jpeg_start_compress(&cinfo
, FALSE
);
115 for(t
=0;t
<height
;t
++) {
116 unsigned char*data2
= &data
[width
*3*t
];
117 jpeg_write_scanlines(&cinfo
, &data2
, 1);
119 jpeg_finish_compress(&cinfo
);
123 jpeg_destroy_compress(&cinfo
);
127 int jpeg_save_gray(unsigned char*data
, unsigned width
, unsigned height
, int quality
, const char*filename
)
129 struct jpeg_destination_mgr mgr
;
130 struct jpeg_compress_struct cinfo
;
131 struct jpeg_error_mgr jerr
;
133 if(filename
) fi
= fopen(filename
, "wb");
136 memset(&cinfo
, 0, sizeof(cinfo
));
137 memset(&jerr
, 0, sizeof(jerr
));
138 memset(&mgr
, 0, sizeof(mgr
));
139 cinfo
.err
= jpeg_std_error(&jerr
);
140 jpeg_create_compress(&cinfo
);
142 mgr
.init_destination
= file_init_destination
;
143 mgr
.empty_output_buffer
= file_empty_output_buffer
;
144 mgr
.term_destination
= file_term_destination
;
146 cinfo
.image_width
= width
;
147 cinfo
.image_height
= height
;
148 cinfo
.input_components
= 1;
149 cinfo
.in_color_space
= JCS_GRAYSCALE
;
150 jpeg_set_defaults(&cinfo
);
151 jpeg_set_quality(&cinfo
,quality
,TRUE
);
152 jpeg_start_compress(&cinfo
, FALSE
);
154 for(t
=0;t
<height
;t
++) {
155 unsigned char*data2
= &data
[width
*t
];
156 jpeg_write_scanlines(&cinfo
, &data2
, 1);
158 jpeg_finish_compress(&cinfo
);
161 jpeg_destroy_compress(&cinfo
);
166 int jpeg_save_to_file(unsigned char*data
, unsigned width
, unsigned height
, int quality
, FILE*_fi
)
168 struct jpeg_destination_mgr mgr
;
169 struct jpeg_compress_struct cinfo
;
170 struct jpeg_error_mgr jerr
;
175 memset(&cinfo
, 0, sizeof(cinfo
));
176 memset(&jerr
, 0, sizeof(jerr
));
177 memset(&mgr
, 0, sizeof(mgr
));
178 cinfo
.err
= jpeg_std_error(&jerr
);
179 jpeg_create_compress(&cinfo
);
181 mgr
.init_destination
= file_init_destination
;
182 mgr
.empty_output_buffer
= file_empty_output_buffer
;
183 mgr
.term_destination
= file_term_destination
;
188 cinfo
.image_width
= width
;
189 cinfo
.image_height
= height
;
190 cinfo
.input_components
= 3;
191 cinfo
.in_color_space
= JCS_RGB
;
192 jpeg_set_defaults(&cinfo
);
193 cinfo
.dct_method
= JDCT_IFAST
;
194 jpeg_set_quality(&cinfo
,quality
,TRUE
);
196 //jpeg_write_tables(&cinfo);
197 //jpeg_suppress_tables(&cinfo, TRUE);
198 jpeg_start_compress(&cinfo
, FALSE
);
200 for(t
=0;t
<height
;t
++) {
201 unsigned char*data2
= &data
[width
*3*t
];
202 jpeg_write_scanlines(&cinfo
, &data2
, 1);
204 jpeg_finish_compress(&cinfo
);
205 jpeg_destroy_compress(&cinfo
);
209 int jpeg_save_to_mem(unsigned char*data
, unsigned width
, unsigned height
, int quality
, unsigned char*_dest
, int _destlen
, int components
)
211 struct jpeg_destination_mgr mgr
;
212 struct jpeg_compress_struct cinfo
;
213 struct jpeg_error_mgr jerr
;
216 memset(&cinfo
, 0, sizeof(cinfo
));
217 memset(&jerr
, 0, sizeof(jerr
));
218 memset(&mgr
, 0, sizeof(mgr
));
219 cinfo
.err
= jpeg_std_error(&jerr
);
220 jpeg_create_compress(&cinfo
);
226 mgr
.init_destination
= mem_init_destination
;
227 mgr
.empty_output_buffer
= mem_empty_output_buffer
;
228 mgr
.term_destination
= mem_term_destination
;
233 cinfo
.image_width
= width
;
234 cinfo
.image_height
= height
;
235 cinfo
.input_components
= 3;
236 cinfo
.in_color_space
= JCS_RGB
;
237 jpeg_set_defaults(&cinfo
);
238 cinfo
.dct_method
= JDCT_IFAST
;
239 jpeg_set_quality(&cinfo
,quality
,TRUE
);
241 jpeg_start_compress(&cinfo
, FALSE
);
242 if(components
== 3) {
243 for(t
=0;t
<height
;t
++) {
244 unsigned char*data2
= &data
[width
*3*t
];
245 jpeg_write_scanlines(&cinfo
, &data2
, 1);
247 } else if(components
== 4) {
248 unsigned char*data2
= malloc(width
*3);
249 for(t
=0;t
<height
;t
++) {
250 unsigned char*line
= &data
[width
*4*t
];
252 for(x
=0;x
<width
;x
++) {
253 data2
[x
*3+0] = line
[x
*4+1];
254 data2
[x
*3+1] = line
[x
*4+2];
255 data2
[x
*3+2] = line
[x
*4+3];
257 jpeg_write_scanlines(&cinfo
, &data2
, 1);
261 fprintf(stderr
, "unsupported number of components in jpeg_save_to_mem()\n");
264 jpeg_finish_compress(&cinfo
);
265 jpeg_destroy_compress(&cinfo
);
269 void mem_init_source (j_decompress_ptr cinfo
)
271 struct jpeg_source_mgr
* mgr
= cinfo
->src
;
272 mgr
->next_input_byte
= data
;
273 mgr
->bytes_in_buffer
= size
;
274 //printf("init %d\n", size - mgr->bytes_in_buffer);
277 boolean
mem_fill_input_buffer (j_decompress_ptr cinfo
)
279 struct jpeg_source_mgr
* mgr
= cinfo
->src
;
280 printf("fill %d\n", size
- mgr
->bytes_in_buffer
);
284 void mem_skip_input_data (j_decompress_ptr cinfo
, long num_bytes
)
286 struct jpeg_source_mgr
* mgr
= cinfo
->src
;
287 printf("skip %d +%ld\n", size
- mgr
->bytes_in_buffer
, num_bytes
);
290 mgr
->next_input_byte
+= num_bytes
;
291 mgr
->bytes_in_buffer
-= num_bytes
;
294 boolean
mem_resync_to_restart (j_decompress_ptr cinfo
, int desired
)
296 struct jpeg_source_mgr
* mgr
= cinfo
->src
;
297 printf("resync %d\n", size
- mgr
->bytes_in_buffer
);
298 mgr
->next_input_byte
= data
;
299 mgr
->bytes_in_buffer
= size
;
303 void mem_term_source (j_decompress_ptr cinfo
)
305 struct jpeg_source_mgr
* mgr
= cinfo
->src
;
306 //printf("term %d\n", size - mgr->bytes_in_buffer);
309 int jpeg_load_from_mem(unsigned char*_data
, int _size
, unsigned char**dest
, unsigned*width
, unsigned*height
)
311 struct jpeg_decompress_struct cinfo
;
312 struct jpeg_error_mgr jerr
;
313 struct jpeg_source_mgr mgr
;
318 jpeg_create_decompress(&cinfo
);
320 mgr
.next_input_byte
= data
;
321 mgr
.bytes_in_buffer
= size
;
322 mgr
.init_source
=mem_init_source
;
323 mgr
.fill_input_buffer
=mem_fill_input_buffer
;
324 mgr
.skip_input_data
=mem_skip_input_data
;
325 mgr
.resync_to_restart
=mem_resync_to_restart
;
326 mgr
.term_source
=mem_term_source
;
328 cinfo
.err
= jpeg_std_error(&jerr
);
331 jpeg_read_header(&cinfo
, TRUE
);
332 cinfo
.out_color_space
== JCS_RGB
;
333 jpeg_start_decompress(&cinfo
);
335 *width
= cinfo
.output_width
;
336 *height
= cinfo
.output_height
;
337 *dest
= malloc(cinfo
.output_width
* cinfo
.output_height
* 4);
339 unsigned char*scanline
= malloc(cinfo
.output_width
* 4);
341 for(y
=0;y
<cinfo
.output_height
;y
++) {
342 unsigned char*to
= &(*dest
)[cinfo
.output_width
*y
*4];
343 jpeg_read_scanlines(&cinfo
,&scanline
,1);
345 for(x
=0;x
<cinfo
.output_width
;x
++) {
347 to
[x
*4 + 1] = scanline
[x
*3 + 0];
348 to
[x
*4 + 2] = scanline
[x
*3 + 1];
349 to
[x
*4 + 3] = scanline
[x
*3 + 2];
354 jpeg_finish_decompress(&cinfo
);
355 jpeg_destroy_decompress(&cinfo
);
359 typedef struct _RGBA
{
360 unsigned char a
,r
,g
,b
;
363 typedef unsigned char U8
;
365 int jpeg_load(const char*filename
, unsigned char**dest
, unsigned*_width
, unsigned*_height
)
367 struct jpeg_decompress_struct cinfo
;
368 struct jpeg_error_mgr jerr
;
369 struct jpeg_source_mgr mgr
;
371 FILE*fi
= fopen(filename
, "rb");
373 fprintf(stderr
, "Couldn't open file %s\n", filename
);
377 cinfo
.err
= jpeg_std_error(&jerr
);
378 jpeg_create_decompress(&cinfo
);
379 jpeg_stdio_src(&cinfo
, fi
);
380 jpeg_read_header(&cinfo
, TRUE
);
381 jpeg_start_decompress(&cinfo
);
383 U8
*scanline
= (U8
*)malloc(4 * cinfo
.output_width
);
385 unsigned int width
= *_width
= cinfo
.output_width
;
386 unsigned int height
= *_height
= cinfo
.output_height
;
387 unsigned long long int image_size
= (unsigned long long)width
* height
* 4;
388 if(image_size
> 0xffffffff) {
393 *dest
= (unsigned char*)malloc(image_size
);
396 for (y
=0;y
<height
;y
++) {
399 RGBA
*line
= &((RGBA
*)(*dest
))[y
*width
];
401 jpeg_read_scanlines(&cinfo
, &js
, 1);
402 if (cinfo
.out_color_space
== JCS_GRAYSCALE
) {
403 for (x
= 0; x
< width
; x
++) {
405 line
[x
].r
= line
[x
].g
= line
[x
].b
= js
[x
];
407 } else if (cinfo
.out_color_space
== JCS_RGB
) {
408 for (x
= width
- 1; x
>= 0; x
--) {
410 line
[x
].r
= js
[x
*3+0];
411 line
[x
].g
= js
[x
*3+1];
412 line
[x
].b
= js
[x
*3+2];
414 } else if (cinfo
.out_color_space
== JCS_YCCK
) {
415 fprintf(stderr
, "Error: Can't convert YCCK to RGB.\n");
417 } else if (cinfo
.out_color_space
== JCS_YCbCr
) {
418 for (x
= 0; x
< width
; x
++) {
419 int y
= js
[x
* 3 + 0];
420 int u
= js
[x
* 3 + 1];
421 int v
= js
[x
* 3 + 1];
423 line
[x
].r
= y
+ ((360 * (v
- 128)) >> 8);
424 line
[x
].g
= y
- ((88 * (u
- 128) + 183 * (v
- 128)) >> 8);
425 line
[x
].b
= y
+ ((455 * (u
- 128)) >> 8);
427 } else if (cinfo
.out_color_space
== JCS_CMYK
) {
428 for (x
= 0; x
< width
; x
++) {
429 int white
= 255 - js
[x
* 4 + 3];
431 line
[x
].r
= white
- ((js
[x
* 4] * white
) >> 8);
432 line
[x
].g
= white
- ((js
[x
* 4 + 1] * white
) >> 8);
433 line
[x
].b
= white
- ((js
[x
* 4 + 2] * white
) >> 8);
440 jpeg_finish_decompress(&cinfo
);
441 jpeg_destroy_decompress(&cinfo
);
446 void jpeg_get_size(const char *filename
, unsigned *width
, unsigned*height
)
448 struct jpeg_decompress_struct cinfo
;
449 struct jpeg_error_mgr jerr
;
453 cinfo
.err
= jpeg_std_error(&jerr
);
454 cinfo
.image_width
= 0;
455 cinfo
.image_height
= 0;
456 jpeg_create_decompress(&cinfo
);
457 if ((fi
= fopen(filename
, "rb")) == NULL
) {
458 fprintf(stderr
, "couldn't open %s\n", filename
);
461 jpeg_stdio_src(&cinfo
, fi
);
462 jpeg_read_header(&cinfo
, TRUE
);
463 *width
= cinfo
.image_width
;
464 *height
= cinfo
.image_height
;
465 jpeg_destroy_decompress(&cinfo
);
471 int jpeg_save(unsigned char*data
, unsigned width
, unsigned height
, int quality
, const char*filename
)
473 fprintf(stderr
, "jpeg_save: No JPEG support compiled in\n");
476 int jpeg_save_to_file(unsigned char*data
, unsigned width
, unsigned height
, int quality
, FILE*fi
)
478 fprintf(stderr
, "jpeg_save_to_file: No JPEG support compiled in\n");
481 int jpeg_save_to_mem(unsigned char*data
, unsigned width
, unsigned height
, int quality
, unsigned char*_dest
, int _destlen
, int components
)
483 fprintf(stderr
, "jpeg_save_tomem: No JPEG support compiled in\n");
486 int jpeg_load_from_mem(unsigned char*_data
, int size
, unsigned char**dest
, unsigned*width
, unsigned*height
)
488 fprintf(stderr
, "jpeg_load_from_mem: No JPEG support compiled in\n");
491 int jpeg_load(const char*filename
, unsigned char**dest
, unsigned*_width
, unsigned*_height
)
493 fprintf(stderr
, "jpeg_load: No JPEG support compiled in\n");
496 void jpeg_get_size(const char *fname
, unsigned *width
, unsigned *height
)
500 fprintf(stderr
, "jpeg_get_size: No JPEG support compiled in\n");