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
, int width
, int 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_to_file(unsigned char*data
, int width
, int height
, int quality
, FILE*_fi
)
129 struct jpeg_destination_mgr mgr
;
130 struct jpeg_compress_struct cinfo
;
131 struct jpeg_error_mgr jerr
;
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
;
149 cinfo
.image_width
= width
;
150 cinfo
.image_height
= height
;
151 cinfo
.input_components
= 3;
152 cinfo
.in_color_space
= JCS_RGB
;
153 jpeg_set_defaults(&cinfo
);
154 cinfo
.dct_method
= JDCT_IFAST
;
155 jpeg_set_quality(&cinfo
,quality
,TRUE
);
157 //jpeg_write_tables(&cinfo);
158 //jpeg_suppress_tables(&cinfo, TRUE);
159 jpeg_start_compress(&cinfo
, FALSE
);
161 for(t
=0;t
<height
;t
++) {
162 unsigned char*data2
= &data
[width
*3*t
];
163 jpeg_write_scanlines(&cinfo
, &data2
, 1);
165 jpeg_finish_compress(&cinfo
);
166 jpeg_destroy_compress(&cinfo
);
170 int jpeg_save_to_mem(unsigned char*data
, int width
, int height
, int quality
, unsigned char*_dest
, int _destlen
)
172 struct jpeg_destination_mgr mgr
;
173 struct jpeg_compress_struct cinfo
;
174 struct jpeg_error_mgr jerr
;
177 memset(&cinfo
, 0, sizeof(cinfo
));
178 memset(&jerr
, 0, sizeof(jerr
));
179 memset(&mgr
, 0, sizeof(mgr
));
180 cinfo
.err
= jpeg_std_error(&jerr
);
181 jpeg_create_compress(&cinfo
);
187 mgr
.init_destination
= mem_init_destination
;
188 mgr
.empty_output_buffer
= mem_empty_output_buffer
;
189 mgr
.term_destination
= mem_term_destination
;
194 cinfo
.image_width
= width
;
195 cinfo
.image_height
= height
;
196 cinfo
.input_components
= 3;
197 cinfo
.in_color_space
= JCS_RGB
;
198 jpeg_set_defaults(&cinfo
);
199 cinfo
.dct_method
= JDCT_IFAST
;
200 jpeg_set_quality(&cinfo
,quality
,TRUE
);
202 jpeg_start_compress(&cinfo
, FALSE
);
203 for(t
=0;t
<height
;t
++) {
204 unsigned char*data2
= &data
[width
*3*t
];
205 jpeg_write_scanlines(&cinfo
, &data2
, 1);
207 jpeg_finish_compress(&cinfo
);
208 jpeg_destroy_compress(&cinfo
);
212 void mem_init_source (j_decompress_ptr cinfo
)
214 struct jpeg_source_mgr
* mgr
= cinfo
->src
;
215 mgr
->next_input_byte
= data
;
216 mgr
->bytes_in_buffer
= size
;
217 //printf("init %d\n", size - mgr->bytes_in_buffer);
220 boolean
mem_fill_input_buffer (j_decompress_ptr cinfo
)
222 struct jpeg_source_mgr
* mgr
= cinfo
->src
;
223 printf("fill %d\n", size
- mgr
->bytes_in_buffer
);
227 void mem_skip_input_data (j_decompress_ptr cinfo
, long num_bytes
)
229 struct jpeg_source_mgr
* mgr
= cinfo
->src
;
230 printf("skip %d +%d\n", size
- mgr
->bytes_in_buffer
, num_bytes
);
233 mgr
->next_input_byte
+= num_bytes
;
234 mgr
->bytes_in_buffer
-= num_bytes
;
237 boolean
mem_resync_to_restart (j_decompress_ptr cinfo
, int desired
)
239 struct jpeg_source_mgr
* mgr
= cinfo
->src
;
240 printf("resync %d\n", size
- mgr
->bytes_in_buffer
);
241 mgr
->next_input_byte
= data
;
242 mgr
->bytes_in_buffer
= size
;
246 void mem_term_source (j_decompress_ptr cinfo
)
248 struct jpeg_source_mgr
* mgr
= cinfo
->src
;
249 //printf("term %d\n", size - mgr->bytes_in_buffer);
252 int jpeg_load_from_mem(unsigned char*_data
, int _size
, unsigned char*dest
, int width
, int height
)
254 struct jpeg_decompress_struct cinfo
;
255 struct jpeg_error_mgr jerr
;
256 struct jpeg_source_mgr mgr
;
262 jpeg_create_decompress(&cinfo
);
264 mgr
.next_input_byte
= data
;
265 mgr
.bytes_in_buffer
= size
;
266 mgr
.init_source
=mem_init_source
;
267 mgr
.fill_input_buffer
=mem_fill_input_buffer
;
268 mgr
.skip_input_data
=mem_skip_input_data
;
269 mgr
.resync_to_restart
=mem_resync_to_restart
;
270 mgr
.term_source
=mem_term_source
;
272 cinfo
.err
= jpeg_std_error(&jerr
);
275 jpeg_read_header(&cinfo
, TRUE
);
276 jpeg_start_decompress(&cinfo
);
278 for(y
=0;y
<height
;y
++) {
279 unsigned char*j
= &dest
[width
*y
*3];
280 jpeg_read_scanlines(&cinfo
,&j
,1);
283 jpeg_finish_decompress(&cinfo
);
284 jpeg_destroy_decompress(&cinfo
);
288 typedef struct _RGBA
{
289 unsigned char a
,r
,g
,b
;
292 typedef unsigned char U8
;
294 int jpeg_load(const char*filename
, unsigned char**dest
, int*_width
, int*_height
)
296 struct jpeg_decompress_struct cinfo
;
297 struct jpeg_error_mgr jerr
;
298 struct jpeg_source_mgr mgr
;
300 FILE*fi
= fopen(filename
, "rb");
302 fprintf(stderr
, "Couldn't open file %s\n", filename
);
306 cinfo
.err
= jpeg_std_error(&jerr
);
307 jpeg_create_decompress(&cinfo
);
308 jpeg_stdio_src(&cinfo
, fi
);
309 jpeg_read_header(&cinfo
, TRUE
);
310 jpeg_start_decompress(&cinfo
);
312 U8
*scanline
= (U8
*)malloc(4 * cinfo
.output_width
);
314 int width
= *_width
= cinfo
.output_width
;
315 int height
= *_height
= cinfo
.output_height
;
316 *dest
= (unsigned char*)malloc(width
*height
*4);
319 for (y
=0;y
<height
;y
++) {
322 RGBA
*line
= &((RGBA
*)(*dest
))[y
*width
];
324 jpeg_read_scanlines(&cinfo
, &js
, 1);
325 if (cinfo
.out_color_space
== JCS_GRAYSCALE
) {
326 for (x
= 0; x
< width
; x
++) {
328 line
[x
].r
= line
[x
].g
= line
[x
].b
= js
[x
];
330 } else if (cinfo
.out_color_space
== JCS_RGB
) {
331 for (x
= width
- 1; x
>= 0; x
--) {
333 line
[x
].r
= js
[x
*3+0];
334 line
[x
].g
= js
[x
*3+1];
335 line
[x
].b
= js
[x
*3+2];
337 } else if (cinfo
.out_color_space
== JCS_YCCK
) {
338 fprintf(stderr
, "Error: Can't convert YCCK to RGB.\n");
340 } else if (cinfo
.out_color_space
== JCS_YCbCr
) {
341 for (x
= 0; x
< width
; x
++) {
342 int y
= js
[x
* 3 + 0];
343 int u
= js
[x
* 3 + 1];
344 int v
= js
[x
* 3 + 1];
346 line
[x
].r
= y
+ ((360 * (v
- 128)) >> 8);
347 line
[x
].g
= y
- ((88 * (u
- 128) + 183 * (v
- 128)) >> 8);
348 line
[x
].b
= y
+ ((455 * (u
- 128)) >> 8);
350 } else if (cinfo
.out_color_space
== JCS_CMYK
) {
351 for (x
= 0; x
< width
; x
++) {
352 int white
= 255 - js
[x
* 4 + 3];
354 line
[x
].r
= white
- ((js
[x
* 4] * white
) >> 8);
355 line
[x
].g
= white
- ((js
[x
* 4 + 1] * white
) >> 8);
356 line
[x
].b
= white
- ((js
[x
* 4 + 2] * white
) >> 8);
363 jpeg_finish_decompress(&cinfo
);
364 jpeg_destroy_decompress(&cinfo
);
370 int jpeg_save(unsigned char*data
, int width
, int height
, int quality
, const char*filename
)
372 fprintf(stderr
, "jpeg_save: No JPEG support compiled in\n");
375 int jpeg_save_to_file(unsigned char*data
, int width
, int height
, int quality
, FILE*fi
)
377 fprintf(stderr
, "jpeg_save_to_file: No JPEG support compiled in\n");
380 int jpeg_save_to_mem(unsigned char*data
, int width
, int height
, int quality
, unsigned char*dest
, int destsize
)
382 fprintf(stderr
, "jpeg_save_tomem: No JPEG support compiled in\n");
385 int jpeg_load_from_mem(unsigned char*_data
, int size
, unsigned char*dest
, int width
, int height
)
387 fprintf(stderr
, "jpeg_load_from_mem: No JPEG support compiled in\n");
390 int jpeg_load(const char*filename
, unsigned char**dest
, int*_width
, int*_height
)
392 fprintf(stderr
, "jpeg_load: No JPEG support compiled in\n");