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
)
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 for(t
=0;t
<height
;t
++) {
243 unsigned char*data2
= &data
[width
*3*t
];
244 jpeg_write_scanlines(&cinfo
, &data2
, 1);
246 jpeg_finish_compress(&cinfo
);
247 jpeg_destroy_compress(&cinfo
);
251 void mem_init_source (j_decompress_ptr cinfo
)
253 struct jpeg_source_mgr
* mgr
= cinfo
->src
;
254 mgr
->next_input_byte
= data
;
255 mgr
->bytes_in_buffer
= size
;
256 //printf("init %d\n", size - mgr->bytes_in_buffer);
259 boolean
mem_fill_input_buffer (j_decompress_ptr cinfo
)
261 struct jpeg_source_mgr
* mgr
= cinfo
->src
;
262 printf("fill %d\n", size
- mgr
->bytes_in_buffer
);
266 void mem_skip_input_data (j_decompress_ptr cinfo
, long num_bytes
)
268 struct jpeg_source_mgr
* mgr
= cinfo
->src
;
269 printf("skip %d +%ld\n", size
- mgr
->bytes_in_buffer
, num_bytes
);
272 mgr
->next_input_byte
+= num_bytes
;
273 mgr
->bytes_in_buffer
-= num_bytes
;
276 boolean
mem_resync_to_restart (j_decompress_ptr cinfo
, int desired
)
278 struct jpeg_source_mgr
* mgr
= cinfo
->src
;
279 printf("resync %d\n", size
- mgr
->bytes_in_buffer
);
280 mgr
->next_input_byte
= data
;
281 mgr
->bytes_in_buffer
= size
;
285 void mem_term_source (j_decompress_ptr cinfo
)
287 struct jpeg_source_mgr
* mgr
= cinfo
->src
;
288 //printf("term %d\n", size - mgr->bytes_in_buffer);
291 int jpeg_load_from_mem(unsigned char*_data
, int _size
, unsigned char**dest
, unsigned*width
, unsigned*height
)
293 struct jpeg_decompress_struct cinfo
;
294 struct jpeg_error_mgr jerr
;
295 struct jpeg_source_mgr mgr
;
300 jpeg_create_decompress(&cinfo
);
302 mgr
.next_input_byte
= data
;
303 mgr
.bytes_in_buffer
= size
;
304 mgr
.init_source
=mem_init_source
;
305 mgr
.fill_input_buffer
=mem_fill_input_buffer
;
306 mgr
.skip_input_data
=mem_skip_input_data
;
307 mgr
.resync_to_restart
=mem_resync_to_restart
;
308 mgr
.term_source
=mem_term_source
;
310 cinfo
.err
= jpeg_std_error(&jerr
);
313 jpeg_read_header(&cinfo
, TRUE
);
314 cinfo
.out_color_space
== JCS_RGB
;
315 jpeg_start_decompress(&cinfo
);
317 *width
= cinfo
.output_width
;
318 *height
= cinfo
.output_height
;
319 *dest
= malloc(cinfo
.output_width
* cinfo
.output_height
* 4);
321 unsigned char*scanline
= malloc(cinfo
.output_width
* 4);
323 for(y
=0;y
<cinfo
.output_height
;y
++) {
324 unsigned char*to
= &(*dest
)[cinfo
.output_width
*y
*4];
325 jpeg_read_scanlines(&cinfo
,&scanline
,1);
327 for(x
=0;x
<cinfo
.output_width
;x
++) {
329 to
[x
*4 + 1] = scanline
[x
*3 + 0];
330 to
[x
*4 + 2] = scanline
[x
*3 + 1];
331 to
[x
*4 + 3] = scanline
[x
*3 + 2];
336 jpeg_finish_decompress(&cinfo
);
337 jpeg_destroy_decompress(&cinfo
);
341 typedef struct _RGBA
{
342 unsigned char a
,r
,g
,b
;
345 typedef unsigned char U8
;
347 int jpeg_load(const char*filename
, unsigned char**dest
, unsigned*_width
, unsigned*_height
)
349 struct jpeg_decompress_struct cinfo
;
350 struct jpeg_error_mgr jerr
;
351 struct jpeg_source_mgr mgr
;
353 FILE*fi
= fopen(filename
, "rb");
355 fprintf(stderr
, "Couldn't open file %s\n", filename
);
359 cinfo
.err
= jpeg_std_error(&jerr
);
360 jpeg_create_decompress(&cinfo
);
361 jpeg_stdio_src(&cinfo
, fi
);
362 jpeg_read_header(&cinfo
, TRUE
);
363 jpeg_start_decompress(&cinfo
);
365 U8
*scanline
= (U8
*)malloc(4 * cinfo
.output_width
);
367 unsigned int width
= *_width
= cinfo
.output_width
;
368 unsigned int height
= *_height
= cinfo
.output_height
;
369 unsigned long long int image_size
= (unsigned long long)width
* height
* 4;
370 if(image_size
> 0xffffffff) {
375 *dest
= (unsigned char*)malloc(image_size
);
378 for (y
=0;y
<height
;y
++) {
381 RGBA
*line
= &((RGBA
*)(*dest
))[y
*width
];
383 jpeg_read_scanlines(&cinfo
, &js
, 1);
384 if (cinfo
.out_color_space
== JCS_GRAYSCALE
) {
385 for (x
= 0; x
< width
; x
++) {
387 line
[x
].r
= line
[x
].g
= line
[x
].b
= js
[x
];
389 } else if (cinfo
.out_color_space
== JCS_RGB
) {
390 for (x
= width
- 1; x
>= 0; x
--) {
392 line
[x
].r
= js
[x
*3+0];
393 line
[x
].g
= js
[x
*3+1];
394 line
[x
].b
= js
[x
*3+2];
396 } else if (cinfo
.out_color_space
== JCS_YCCK
) {
397 fprintf(stderr
, "Error: Can't convert YCCK to RGB.\n");
399 } else if (cinfo
.out_color_space
== JCS_YCbCr
) {
400 for (x
= 0; x
< width
; x
++) {
401 int y
= js
[x
* 3 + 0];
402 int u
= js
[x
* 3 + 1];
403 int v
= js
[x
* 3 + 1];
405 line
[x
].r
= y
+ ((360 * (v
- 128)) >> 8);
406 line
[x
].g
= y
- ((88 * (u
- 128) + 183 * (v
- 128)) >> 8);
407 line
[x
].b
= y
+ ((455 * (u
- 128)) >> 8);
409 } else if (cinfo
.out_color_space
== JCS_CMYK
) {
410 for (x
= 0; x
< width
; x
++) {
411 int white
= 255 - js
[x
* 4 + 3];
413 line
[x
].r
= white
- ((js
[x
* 4] * white
) >> 8);
414 line
[x
].g
= white
- ((js
[x
* 4 + 1] * white
) >> 8);
415 line
[x
].b
= white
- ((js
[x
* 4 + 2] * white
) >> 8);
422 jpeg_finish_decompress(&cinfo
);
423 jpeg_destroy_decompress(&cinfo
);
428 void jpeg_get_size(const char *filename
, unsigned *width
, unsigned*height
)
430 struct jpeg_decompress_struct cinfo
;
431 struct jpeg_error_mgr jerr
;
435 cinfo
.err
= jpeg_std_error(&jerr
);
436 cinfo
.image_width
= 0;
437 cinfo
.image_height
= 0;
438 jpeg_create_decompress(&cinfo
);
439 if ((fi
= fopen(filename
, "rb")) == NULL
) {
440 fprintf(stderr
, "couldn't open %s\n", filename
);
443 jpeg_stdio_src(&cinfo
, fi
);
444 jpeg_read_header(&cinfo
, TRUE
);
445 *width
= cinfo
.image_width
;
446 *height
= cinfo
.image_height
;
447 jpeg_destroy_decompress(&cinfo
);
453 int jpeg_save(unsigned char*data
, unsigned width
, unsigned height
, int quality
, const char*filename
)
455 fprintf(stderr
, "jpeg_save: No JPEG support compiled in\n");
458 int jpeg_save_to_file(unsigned char*data
, unsigned width
, unsigned height
, int quality
, FILE*fi
)
460 fprintf(stderr
, "jpeg_save_to_file: No JPEG support compiled in\n");
463 int jpeg_save_to_mem(unsigned char*data
, unsigned width
, unsigned height
, int quality
, unsigned char*dest
, int destsize
)
465 fprintf(stderr
, "jpeg_save_tomem: No JPEG support compiled in\n");
468 int jpeg_load_from_mem(unsigned char*_data
, int size
, unsigned char**dest
, unsigned*width
, unsigned*height
)
470 fprintf(stderr
, "jpeg_load_from_mem: No JPEG support compiled in\n");
473 int jpeg_load(const char*filename
, unsigned char**dest
, unsigned*_width
, unsigned*_height
)
475 fprintf(stderr
, "jpeg_load: No JPEG support compiled in\n");
478 void jpeg_get_size(const char *fname
, unsigned *width
, unsigned *height
)
482 fprintf(stderr
, "jpeg_get_size: No JPEG support compiled in\n");