Instrument Neutral Distributed Interface INDI 2.2.5
jpegutils.c
Go to the documentation of this file.
1/*
2 * jpegutils.c: Some Utility programs for dealing with
3 * JPEG encoded images
4 *
5 * Copyright (C) 1999 Rainer Johanni <[email protected]>
6 * Copyright (C) 2001 pHilipp Zabel <[email protected]>
7 * Copyright (C) 2008 Angel Carpintero <[email protected]>
8 *
9 * based on jdatasrc.c and jdatadst.c from the Independent
10 * JPEG Group's software by Thomas G. Lane
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25 */
26
27#include "jpegutils.h"
28
29#include <jpeglib.h>
30#include <jerror.h>
31
32#include <assert.h>
33#include <setjmp.h>
34#include <stdint.h>
35#include <stdlib.h>
36#include <string.h>
37
38/*
39* jpeg_data: buffer with input / output jpeg
40* len: Length of jpeg buffer
41* itype: 0: Not interlaced
42* 1: Interlaced, Top field first
43* 2: Interlaced, Bottom field first
44* ctype Chroma format for decompression.
45* Currently only Y4M_CHROMA_{420JPEG,422} are available
46* raw0 buffer with input / output raw Y channel
47* raw1 buffer with input / output raw U/Cb channel
48* raw2 buffer with input / output raw V/Cr channel
49* width width of Y channel (width of U/V is width/2)
50* height height of Y channel (height of U/V is height/2)
51*/
52
53static void jpeg_buffer_src(j_decompress_ptr cinfo, unsigned char *buffer, long num);
54static void jpeg_buffer_dest(j_compress_ptr cinfo, unsigned char *buffer, long len);
55static void jpeg_skip_ff(j_decompress_ptr cinfo);
56
57/*******************************************************************
58 * *
59 * The following routines define a JPEG Source manager which *
60 * just reads from a given buffer (instead of a file as in *
61 * the jpeg library) *
62 * *
63 *******************************************************************/
64
65/*
66 * Initialize source --- called by jpeg_read_header
67 * before any data is actually read.
68 */
69
70static void init_source(j_decompress_ptr cinfo)
71{
72 (void)cinfo;
73 /* no work necessary here */
74}
75
76/*
77 * Fill the input buffer --- called whenever buffer is emptied.
78 *
79 * Should never be called since all data should be already provided.
80 * Is nevertheless sometimes called - sets the input buffer to data
81 * which is the JPEG EOI marker;
82 *
83 */
84
85static uint8_t EOI_data[2] = { 0xFF, 0xD9 };
86
87static boolean fill_input_buffer(j_decompress_ptr cinfo)
88{
89 cinfo->src->next_input_byte = EOI_data;
90 cinfo->src->bytes_in_buffer = 2;
91 return TRUE;
92}
93
94/*
95 * Skip data --- used to skip over a potentially large amount of
96 * uninteresting data (such as an APPn marker).
97 *
98 */
99
100static void skip_input_data(j_decompress_ptr cinfo, long num_bytes)
101{
102 if (num_bytes > 0)
103 {
104 if (num_bytes > (long)cinfo->src->bytes_in_buffer)
105 num_bytes = (long)cinfo->src->bytes_in_buffer;
106 cinfo->src->next_input_byte += (size_t)num_bytes;
107 cinfo->src->bytes_in_buffer -= (size_t)num_bytes;
108 }
109}
110
111/*
112 * Terminate source --- called by jpeg_finish_decompress
113 * after all data has been read. Often a no-op.
114 */
115
116static void term_source(j_decompress_ptr cinfo)
117{
118 (void)cinfo;
119 /* no work necessary here */
120}
121
122/*
123 * Prepare for input from a data buffer.
124 */
125
126static void jpeg_buffer_src(j_decompress_ptr cinfo, unsigned char *buffer, long num)
127{
128 /* The source object and input buffer are made permanent so that a series
129 * of JPEG images can be read from the same buffer by calling jpeg_buffer_src
130 * only before the first one. (If we discarded the buffer at the end of
131 * one image, we'd likely lose the start of the next one.)
132 * This makes it unsafe to use this manager and a different source
133 * manager serially with the same JPEG object. Caveat programmer.
134 */
135 if (cinfo->src == NULL) /* first time for this JPEG object? */
136 {
137 cinfo->src = (struct jpeg_source_mgr *)(*cinfo->mem->alloc_small)((j_common_ptr)cinfo, JPOOL_PERMANENT,
138 sizeof(struct jpeg_source_mgr));
139 }
140
141 cinfo->src->init_source = init_source;
142 cinfo->src->fill_input_buffer = fill_input_buffer;
143 cinfo->src->skip_input_data = skip_input_data;
144 cinfo->src->resync_to_restart = jpeg_resync_to_restart; /* use default method */
145 cinfo->src->term_source = term_source;
146 cinfo->src->bytes_in_buffer = num;
147 cinfo->src->next_input_byte = (JOCTET *)buffer;
148}
149
150/*
151 * jpeg_skip_ff is not a part of the source manager but it is
152 * particularly useful when reading several images from the same buffer:
153 * It should be called to skip padding 0xff bytes between images.
154 */
155
156static void jpeg_skip_ff(j_decompress_ptr cinfo)
157{
158 while (cinfo->src->bytes_in_buffer > 1 && cinfo->src->next_input_byte[0] == 0xff &&
159 cinfo->src->next_input_byte[1] == 0xff)
160 {
161 cinfo->src->bytes_in_buffer--;
162 cinfo->src->next_input_byte++;
163 }
164}
165
166/*******************************************************************
167 * *
168 * The following routines define a JPEG Destination manager *
169 * which just reads from a given buffer (instead of a file *
170 * as in the jpeg library) *
171 * *
172 *******************************************************************/
173
174/*
175 * Initialize destination --- called by jpeg_start_compress
176 * before any data is actually written.
177 */
178
179static void init_destination(j_compress_ptr cinfo)
180{
181 (void)cinfo;
182 /* No work necessary here */
183}
184
185/*
186 * Empty the output buffer --- called whenever buffer fills up.
187 *
188 * Should never be called since all data should be written to the buffer.
189 * If it gets called, the given jpeg buffer was too small.
190 *
191 */
192
193static boolean empty_output_buffer(j_compress_ptr cinfo)
194{
195 (void)cinfo;
196 return TRUE;
197}
198
199/*
200 * Terminate destination --- called by jpeg_finish_compress
201 * after all data has been written. Usually needs to flush buffer.
202 *
203 * NB: *not* called by jpeg_abort or jpeg_destroy; surrounding
204 * application must deal with any cleanup that should happen even
205 * for error exit.
206 */
207
208static void term_destination(j_compress_ptr cinfo)
209{
210 (void)cinfo;
211 /* no work necessary here */
212}
213
214/*
215 * Prepare for output to a stdio stream.
216 * The caller must have already opened the stream, and is responsible
217 * for closing it after finishing compression.
218 */
219
220static void jpeg_buffer_dest(j_compress_ptr cinfo, unsigned char *buf, long len)
221{
222 /* The destination object is made permanent so that multiple JPEG images
223 * can be written to the same file without re-executing jpeg_stdio_dest.
224 * This makes it dangerous to use this manager and a different destination
225 * manager serially with the same JPEG object, because their private object
226 * sizes may be different. Caveat programmer.
227 */
228 if (cinfo->dest == NULL) /* first time for this JPEG object? */
229 {
230 cinfo->dest = (struct jpeg_destination_mgr *)(*cinfo->mem->alloc_small)((j_common_ptr)cinfo, JPOOL_PERMANENT,
231 sizeof(struct jpeg_destination_mgr));
232 }
233
234 cinfo->dest->init_destination = init_destination;
235 cinfo->dest->empty_output_buffer = empty_output_buffer;
236 cinfo->dest->term_destination = term_destination;
237 cinfo->dest->free_in_buffer = len;
238 cinfo->dest->next_output_byte = (JOCTET *)buf;
239}
240
241/*******************************************************************
242 * *
243 * decode_jpeg_data: Decode a (possibly interlaced) JPEG frame *
244 * *
245 *******************************************************************/
246
247/*
248 * ERROR HANDLING:
249 *
250 * We want in all cases to return to the user.
251 * The following kind of error handling is from the
252 * example.c file in the Independent JPEG Group's JPEG software
253 */
254
256{
257 struct jpeg_error_mgr pub; /* "public" fields */
258 jmp_buf setjmp_buffer; /* for return to caller */
259
260 /* original emit_message method */
261 JMETHOD(void, original_emit_message, (j_common_ptr cinfo, int msg_level));
262 /* was a corrupt-data warning seen */
264};
265
266static void my_error_exit(j_common_ptr cinfo)
267{
268 /* cinfo->err really points to a my_error_mgr struct, so coerce pointer */
269 struct my_error_mgr *myerr = (struct my_error_mgr *)cinfo->err;
270
271 /* Always display the message. */
272 /* We could postpone this until after returning, if we chose. */
273 (*cinfo->err->output_message)(cinfo);
274
275 /* Return control to the setjmp point */
276 longjmp(myerr->setjmp_buffer, 1);
277}
278
279static void my_emit_message(j_common_ptr cinfo, int msg_level)
280{
281 /* cinfo->err really points to a my_error_mgr struct, so coerce pointer */
282 struct my_error_mgr *myerr = (struct my_error_mgr *)cinfo->err;
283
284 if (msg_level < 0)
285 myerr->warning_seen = 1;
286
287 /* call original emit_message() */
288 /* geehalel (myerr->original_emit_message)(cinfo, msg_level); */
289}
290
291#define MAX_LUMA_WIDTH 4096
292#define MAX_CHROMA_WIDTH 2048
293
294static unsigned char buf0[16][MAX_LUMA_WIDTH];
295static unsigned char buf1[8][MAX_CHROMA_WIDTH];
296static unsigned char buf2[8][MAX_CHROMA_WIDTH];
297static unsigned char chr1[8][MAX_CHROMA_WIDTH];
298static unsigned char chr2[8][MAX_CHROMA_WIDTH];
299
300#if 1 /* generation of 'std' Huffman tables... */
301
302static void add_huff_table(j_decompress_ptr dinfo, JHUFF_TBL **htblptr, const UINT8 *bits, const UINT8 *val)
303/* Define a Huffman table */
304{
305 int nsymbols, len;
306
307 if (*htblptr == NULL)
308 *htblptr = jpeg_alloc_huff_table((j_common_ptr)dinfo);
309
310 /* Copy the number-of-symbols-of-each-code-length counts */
311 memcpy((*htblptr)->bits, bits, sizeof((*htblptr)->bits));
312
313 /* Validate the counts. We do this here mainly so we can copy the right
314 * number of symbols from the val[] array, without risking marching off
315 * the end of memory. jchuff.c will do a more thorough test later.
316 */
317 nsymbols = 0;
318
319 for (len = 1; len <= 16; len++)
320 nsymbols += bits[len];
321
322 if (nsymbols < 1 || nsymbols > 256)
323 fprintf(stderr, "%s: Given jpeg buffer was too small", __FUNCTION__);
324
325 memcpy((*htblptr)->huffval, val, nsymbols * sizeof(UINT8));
326}
327
328static void std_huff_tables(j_decompress_ptr dinfo)
329/* Set up the standard Huffman tables (cf. JPEG standard section K.3) */
330/* IMPORTANT: these are only valid for 8-bit data precision! */
331{
332 static const UINT8 bits_dc_luminance[17] = { /* 0-base */ 0,
333 0,
334 1,
335 5,
336 1,
337 1,
338 1,
339 1,
340 1,
341 1,
342 0,
343 0,
344 0,
345 0,
346 0,
347 0,
348 0 };
349 static const UINT8 val_dc_luminance[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
350
351 static const UINT8 bits_dc_chrominance[17] = { /* 0-base */ 0,
352 0,
353 3,
354 1,
355 1,
356 1,
357 1,
358 1,
359 1,
360 1,
361 1,
362 1,
363 0,
364 0,
365 0,
366 0,
367 0 };
368 static const UINT8 val_dc_chrominance[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
369
370 static const UINT8 bits_ac_luminance[17] = { /* 0-base */ 0,
371 0,
372 2,
373 1,
374 3,
375 3,
376 2,
377 4,
378 3,
379 5,
380 5,
381 4,
382 4,
383 0,
384 0,
385 1,
386 0x7d };
387 static const UINT8 val_ac_luminance[] = {
388 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, 0x22, 0x71,
389 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08, 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0, 0x24, 0x33, 0x62, 0x72,
390 0x82, 0x09, 0x0a, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37,
391 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
392 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x83,
393 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3,
394 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3,
395 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
396 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa
397 };
398
399 static const UINT8 bits_ac_chrominance[17] = { /* 0-base */ 0,
400 0,
401 2,
402 1,
403 2,
404 4,
405 4,
406 3,
407 4,
408 7,
409 5,
410 4,
411 4,
412 0,
413 1,
414 2,
415 0x77 };
416 static const UINT8 val_ac_chrominance[] = {
417 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, 0x13, 0x22,
418 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0, 0x15, 0x62, 0x72, 0xd1,
419 0x0a, 0x16, 0x24, 0x34, 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36,
420 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
421 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a,
422 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a,
423 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba,
424 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda,
425 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa
426 };
427
428 add_huff_table(dinfo, &dinfo->dc_huff_tbl_ptrs[0], bits_dc_luminance, val_dc_luminance);
429 add_huff_table(dinfo, &dinfo->ac_huff_tbl_ptrs[0], bits_ac_luminance, val_ac_luminance);
430 add_huff_table(dinfo, &dinfo->dc_huff_tbl_ptrs[1], bits_dc_chrominance, val_dc_chrominance);
431 add_huff_table(dinfo, &dinfo->ac_huff_tbl_ptrs[1], bits_ac_chrominance, val_ac_chrominance);
432}
433
434static void guarantee_huff_tables(j_decompress_ptr dinfo)
435{
436 if ((dinfo->dc_huff_tbl_ptrs[0] == NULL) && (dinfo->dc_huff_tbl_ptrs[1] == NULL) &&
437 (dinfo->ac_huff_tbl_ptrs[0] == NULL) && (dinfo->ac_huff_tbl_ptrs[1] == NULL))
438 {
439 std_huff_tables(dinfo);
440 }
441}
442
443#endif /* ...'std' Huffman table generation */
444
445/*
446 * jpeg_data: Buffer with jpeg data to decode
447 * len: Length of buffer
448 * itype: 0: Not interlaced
449 * 1: Interlaced, Top field first
450 * 2: Interlaced, Bottom field first
451 * ctype Chroma format for decompression.
452 * Currently only Y4M_CHROMA_{420JPEG,422} are available
453 * returns:
454 * -1 on fatal error
455 * 0 on success
456 * 1 if jpeg lib threw a "corrupt jpeg data" warning.
457 * in this case, "a damaged output image is likely."
458 *
459 */
460
461int decode_jpeg_raw(unsigned char *jpeg_data, int len, int itype, int ctype, unsigned int width, unsigned int height,
462 unsigned char *raw0, unsigned char *raw1, unsigned char *raw2)
463{
464 int numfields, hsf[3], field;
465 unsigned int yl, yc;
466 int i, xsl, xsc, xs, hdown;
467 unsigned int x, y = 0, vsf[3], xd;
468
469 JSAMPROW row0[16] = { buf0[0], buf0[1], buf0[2], buf0[3], buf0[4], buf0[5], buf0[6], buf0[7],
470 buf0[8], buf0[9], buf0[10], buf0[11], buf0[12], buf0[13], buf0[14], buf0[15] };
471
472 JSAMPROW row1[8] = { buf1[0], buf1[1], buf1[2], buf1[3], buf1[4], buf1[5], buf1[6], buf1[7] };
473
474 JSAMPROW row2[16] = { buf2[0], buf2[1], buf2[2], buf2[3], buf2[4], buf2[5], buf2[6], buf2[7] };
475
476 JSAMPROW row1_444[16], row2_444[16];
477
478 JSAMPARRAY scanarray[3] = { row0, row1, row2 };
479
480 struct jpeg_decompress_struct dinfo;
481 struct my_error_mgr jerr;
482
483 /* We set up the normal JPEG error routines, then override error_exit. */
484 dinfo.err = jpeg_std_error(&jerr.pub);
485 jerr.pub.error_exit = my_error_exit;
486 /* also hook the emit_message routine to note corrupt-data warnings */
487 jerr.original_emit_message = jerr.pub.emit_message;
488 jerr.pub.emit_message = my_emit_message;
489 jerr.warning_seen = 0;
490
491 /* Establish the setjmp return context for my_error_exit to use. */
492 if (setjmp(jerr.setjmp_buffer))
493 {
494 /* If we get here, the JPEG code has signaled an error. */
495 jpeg_destroy_decompress(&dinfo);
496 return -1;
497 }
498
499 jpeg_create_decompress(&dinfo);
500
501 jpeg_buffer_src(&dinfo, jpeg_data, len);
502
503 /* Read header, make some checks and try to figure out what the
504 user really wants */
505
506 jpeg_read_header(&dinfo, TRUE);
507 dinfo.raw_data_out = TRUE;
508 dinfo.out_color_space = JCS_YCbCr;
509 dinfo.dct_method = JDCT_IFAST;
510 guarantee_huff_tables(&dinfo);
511 jpeg_start_decompress(&dinfo);
512
513 if (dinfo.output_components != 3)
514 {
515 fprintf(stderr, "%s: Output components of JPEG image = %d, must be 3", __FUNCTION__, dinfo.output_components);
516 goto ERR_EXIT;
517 }
518
519 for (i = 0; i < 3; i++)
520 {
521 hsf[i] = dinfo.comp_info[i].h_samp_factor;
522 vsf[i] = dinfo.comp_info[i].v_samp_factor;
523 }
524
525 if ((hsf[0] != 2 && hsf[0] != 1) || hsf[1] != 1 || hsf[2] != 1 || (vsf[0] != 1 && vsf[0] != 2) || vsf[1] != 1 ||
526 vsf[2] != 1)
527 {
528 fprintf(stderr,
529 "%s: Unsupported sampling factors, hsf=(%d, %d, %d) "
530 "vsf=(%d, %d, %d) !",
531 __FUNCTION__, hsf[0], hsf[1], hsf[2], vsf[0], vsf[1], vsf[2]);
532 goto ERR_EXIT;
533 }
534
535 if (hsf[0] == 1)
536 {
537 if (height % 8 != 0)
538 {
539 fprintf(stderr,
540 "%s: YUV 4:4:4 sampling, but image height %d "
541 "not dividable by 8 !",
542 __FUNCTION__, height);
543 goto ERR_EXIT;
544 }
545
546 for (y = 0; y < 16; y++) // allocate a special buffer for the extra sampling depth
547 {
548 row1_444[y] = (unsigned char *)malloc(dinfo.output_width * sizeof(unsigned char));
549 row2_444[y] = (unsigned char *)malloc(dinfo.output_width * sizeof(unsigned char));
550 }
551 scanarray[1] = row1_444;
552 scanarray[2] = row2_444;
553 }
554
555 /* Height match image height or be exact twice the image height */
556
557 if (dinfo.output_height == height)
558 {
559 numfields = 1;
560 }
561 else if (2 * dinfo.output_height == height)
562 {
563 numfields = 2;
564 }
565 else
566 {
567 fprintf(stderr,
568 "%s: Read JPEG: requested height = %d, "
569 "height of image = %d",
570 __FUNCTION__, height, dinfo.output_height);
571 goto ERR_EXIT;
572 }
573
574 /* Width is more flexible */
575
576 if (dinfo.output_width > MAX_LUMA_WIDTH)
577 {
578 fprintf(stderr, "%s: Image width of %d exceeds max", __FUNCTION__, dinfo.output_width);
579 goto ERR_EXIT;
580 }
581
582 if (width < 2 * dinfo.output_width / 3)
583 {
584 /* Downsample 2:1 */
585 hdown = 1;
586 if (2 * width < dinfo.output_width)
587 xsl = (dinfo.output_width - 2 * width) / 2;
588 else
589 xsl = 0;
590 }
591 else if (width == 2 * dinfo.output_width / 3)
592 {
593 /* special case of 3:2 downsampling */
594 hdown = 2;
595 xsl = 0;
596 }
597 else
598 {
599 /* No downsampling */
600 hdown = 0;
601 if (width < dinfo.output_width)
602 xsl = (dinfo.output_width - width) / 2;
603 else
604 xsl = 0;
605 }
606
607 /* Make xsl even, calculate xsc */
608
609 xsl = xsl & ~1;
610 xsc = xsl / 2;
611
612 yl = yc = 0;
613
614 for (field = 0; field < numfields; field++)
615 {
616 if (field > 0)
617 {
618 jpeg_read_header(&dinfo, TRUE);
619 dinfo.raw_data_out = TRUE;
620 dinfo.out_color_space = JCS_YCbCr;
621 dinfo.dct_method = JDCT_IFAST;
622 jpeg_start_decompress(&dinfo);
623 }
624
625 if (numfields == 2)
626 {
627 switch (itype)
628 {
630 yl = yc = field;
631 break;
633 yl = yc = (1 - field);
634 break;
635 default:
636 fprintf(stderr, "%s: Input is interlaced but no interlacing set", __FUNCTION__);
637 goto ERR_EXIT;
638 }
639 }
640 else
641 {
642 yl = yc = 0;
643 }
644
645 while (dinfo.output_scanline < dinfo.output_height)
646 {
647 /* read raw data */
648 jpeg_read_raw_data(&dinfo, scanarray, 8 * vsf[0]);
649
650 for (y = 0; y < 8 * vsf[0] && yl < height; yl += numfields, y++)
651 {
652 xd = yl * width;
653 xs = xsl;
654
655 if (hdown == 0)
656 {
657 for (x = 0; x < width; x++)
658 raw0[xd++] = row0[y][xs++];
659 }
660 else if (hdown == 1)
661 {
662 for (x = 0; x < width; x++, xs += 2)
663 raw0[xd++] = (row0[y][xs] + row0[y][xs + 1]) >> 1;
664 }
665 else
666 {
667 for (x = 0; x < width / 2; x++, xd += 2, xs += 3)
668 {
669 raw0[xd] = (2 * row0[y][xs] + row0[y][xs + 1]) / 3;
670 raw0[xd + 1] = (2 * row0[y][xs + 2] + row0[y][xs + 1]) / 3;
671 }
672 }
673 }
674
675 /* Horizontal downsampling of chroma */
676
677 for (y = 0; y < 8; y++)
678 {
679 xs = xsc;
680
681 if (hsf[0] == 1)
682 for (x = 0; x < width / 2; x++, xs++)
683 {
684 row1[y][xs] = (row1_444[y][2 * x] + row1_444[y][2 * x + 1]) >> 1;
685 row2[y][xs] = (row2_444[y][2 * x] + row2_444[y][2 * x + 1]) >> 1;
686 }
687
688 xs = xsc;
689 if (hdown == 0)
690 {
691 for (x = 0; x < width / 2; x++, xs++)
692 {
693 chr1[y][x] = row1[y][xs];
694 chr2[y][x] = row2[y][xs];
695 }
696 }
697 else if (hdown == 1)
698 {
699 for (x = 0; x < width / 2; x++, xs += 2)
700 {
701 chr1[y][x] = (row1[y][xs] + row1[y][xs + 1]) >> 1;
702 chr2[y][x] = (row2[y][xs] + row2[y][xs + 1]) >> 1;
703 }
704 }
705 else
706 {
707 for (x = 0; x < width / 2; x += 2, xs += 3)
708 {
709 chr1[y][x] = (2 * row1[y][xs] + row1[y][xs + 1]) / 3;
710 chr1[y][x + 1] = (2 * row1[y][xs + 2] + row1[y][xs + 1]) / 3;
711 chr2[y][x] = (2 * row2[y][xs] + row2[y][xs + 1]) / 3;
712 chr2[y][x + 1] = (2 * row2[y][xs + 2] + row2[y][xs + 1]) / 3;
713 }
714 }
715 }
716
717 /* Vertical resampling of chroma */
718
719 switch (ctype)
720 {
721 case Y4M_CHROMA_422:
722 if (vsf[0] == 1)
723 {
724 /* Just copy */
725 for (y = 0; y < 8 && yc < height; y++, yc += numfields)
726 {
727 xd = yc * width / 2;
728
729 for (x = 0; x < width / 2; x++, xd++)
730 {
731 raw1[xd] = chr1[y][x];
732 raw2[xd] = chr2[y][x];
733 }
734 }
735 }
736 else
737 {
738 /* upsample */
739 for (y = 0; y < 8 && yc < height; y++)
740 {
741 xd = yc * width / 2;
742
743 for (x = 0; x < width / 2; x++, xd++)
744 {
745 raw1[xd] = chr1[y][x];
746 raw2[xd] = chr2[y][x];
747 }
748
749 yc += numfields;
750 xd = yc * width / 2;
751
752 for (x = 0; x < width / 2; x++, xd++)
753 {
754 raw1[xd] = chr1[y][x];
755 raw2[xd] = chr2[y][x];
756 }
757
758 yc += numfields;
759 }
760 }
761 break;
762 default:
763 /*
764 * should be case Y4M_CHROMA_420JPEG: but use default: for compatibility. Some
765 * pass things like '420' in with the expectation that anything other than
766 * Y4M_CHROMA_422 will default to 420JPEG.
767 */
768 if (vsf[0] == 1)
769 {
770 /* Really downsample */
771 for (y = 0; y < 8 && yc < height/2; y += 2, yc += numfields)
772 {
773 xd = yc * width / 2;
774
775 for (x = 0; x < width / 2; x++, xd++)
776 {
777 assert(xd < (width * height / 4));
778 raw1[xd] = (chr1[y][x] + chr1[y + 1][x]) >> 1;
779 raw2[xd] = (chr2[y][x] + chr2[y + 1][x]) >> 1;
780 }
781 }
782 }
783 else
784 {
785 /* Just copy */
786 for (y = 0; y < 8 && yc < height/2; y++, yc += numfields)
787 {
788 xd = yc * width / 2;
789
790 for (x = 0; x < width / 2; x++, xd++)
791 {
792 raw1[xd] = chr1[y][x];
793 raw2[xd] = chr2[y][x];
794 }
795 }
796 }
797 break;
798 }
799 }
800
801 (void)jpeg_finish_decompress(&dinfo);
802 if (field == 0 && numfields > 1)
803 jpeg_skip_ff(&dinfo);
804 }
805
806 if (hsf[0] == 1)
807 {
808 for (y = 0; y < 16; y++) // allocate a special buffer for the extra sampling depth
809 {
810 free(row1_444[y]);
811 free(row2_444[y]);
812 }
813 }
814
815 jpeg_destroy_decompress(&dinfo);
816
817 if (jerr.warning_seen)
818 return 1;
819 else
820 return 0;
821
822ERR_EXIT:
823 jpeg_destroy_decompress(&dinfo);
824 return -1;
825}
826
827/*
828 * jpeg_data: Buffer with jpeg data to decode, must be grayscale mode
829 * len: Length of buffer
830 * itype: 0: Not interlaced
831 * 1: Interlaced, Top field first
832 * 2: Interlaced, Bottom field first
833 * ctype Chroma format for decompression.
834 * Currently only Y4M_CHROMA_{420JPEG,422} are available
835 */
836
837int decode_jpeg_gray_raw(unsigned char *jpeg_data, int len, int itype, int ctype, unsigned int width,
838 unsigned int height, unsigned char *raw0, unsigned char *raw1, unsigned char *raw2)
839{
840 int numfields, field, yl, yc, xsl, xsc, xs, xd, hdown;
841 unsigned int x, y, vsf[3];
842
843 JSAMPROW row0[16] = { buf0[0], buf0[1], buf0[2], buf0[3], buf0[4], buf0[5], buf0[6], buf0[7],
844 buf0[8], buf0[9], buf0[10], buf0[11], buf0[12], buf0[13], buf0[14], buf0[15] };
845
846 JSAMPARRAY scanarray[3] = { row0 };
847 struct jpeg_decompress_struct dinfo;
848 struct my_error_mgr jerr;
849
850 /* We set up the normal JPEG error routines, then override error_exit. */
851 dinfo.err = jpeg_std_error(&jerr.pub);
852 jerr.pub.error_exit = my_error_exit;
853
854 /* Establish the setjmp return context for my_error_exit to use. */
855 if (setjmp(jerr.setjmp_buffer))
856 {
857 /* If we get here, the JPEG code has signaled an error. */
858 jpeg_destroy_decompress(&dinfo);
859 return -1;
860 }
861
862 jpeg_create_decompress(&dinfo);
863
864 jpeg_buffer_src(&dinfo, jpeg_data, len);
865
866 /* Read header, make some checks and try to figure out what the
867 user really wants */
868
869 jpeg_read_header(&dinfo, TRUE);
870 dinfo.raw_data_out = TRUE;
871 dinfo.out_color_space = JCS_GRAYSCALE;
872 dinfo.dct_method = JDCT_IFAST;
873
874 if (dinfo.jpeg_color_space != JCS_GRAYSCALE)
875 {
876 fprintf(stderr, "%s: Expected grayscale colorspace for JPEG raw decoding", __FUNCTION__);
877 goto ERR_EXIT;
878 }
879
880 guarantee_huff_tables(&dinfo);
881 jpeg_start_decompress(&dinfo);
882
883// hsf[0] = 1;
884// hsf[1] = 1;
885// hsf[2] = 1;
886 vsf[0] = 1;
887 vsf[1] = 1;
888 vsf[2] = 1;
889
890 /* Height match image height or be exact twice the image height */
891
892 if (dinfo.output_height == height)
893 {
894 numfields = 1;
895 }
896 else if (2 * dinfo.output_height == height)
897 {
898 numfields = 2;
899 }
900 else
901 {
902 fprintf(stderr,
903 "%s: Read JPEG: requested height = %d, "
904 "height of image = %d",
905 __FUNCTION__, height, dinfo.output_height);
906 goto ERR_EXIT;
907 }
908
909 /* Width is more flexible */
910
911 if (dinfo.output_width > MAX_LUMA_WIDTH)
912 {
913 fprintf(stderr, "%s: Image width of %d exceeds max", __FUNCTION__, dinfo.output_width);
914 goto ERR_EXIT;
915 }
916
917 if (width < 2 * dinfo.output_width / 3)
918 {
919 /* Downsample 2:1 */
920 hdown = 1;
921 if (2 * width < dinfo.output_width)
922 xsl = (dinfo.output_width - 2 * width) / 2;
923 else
924 xsl = 0;
925 }
926 else if (width == 2 * dinfo.output_width / 3)
927 {
928 /* special case of 3:2 downsampling */
929 hdown = 2;
930 xsl = 0;
931 }
932 else
933 {
934 /* No downsampling */
935 hdown = 0;
936 if (width < dinfo.output_width)
937 xsl = (dinfo.output_width - width) / 2;
938 else
939 xsl = 0;
940 }
941
942 /* Make xsl even, calculate xsc */
943
944 xsl = xsl & ~1;
945 xsc = xsl / 2;
946
947 yl = yc = 0;
948
949 for (field = 0; field < numfields; field++)
950 {
951 if (field > 0)
952 {
953 jpeg_read_header(&dinfo, TRUE);
954 dinfo.raw_data_out = TRUE;
955 dinfo.out_color_space = JCS_GRAYSCALE;
956 dinfo.dct_method = JDCT_IFAST;
957 jpeg_start_decompress(&dinfo);
958 }
959
960 if (numfields == 2)
961 {
962 switch (itype)
963 {
965 yl = yc = field;
966 break;
968 yl = yc = (1 - field);
969 break;
970 default:
971 fprintf(stderr, "%s: Input is interlaced but no interlacing set", __FUNCTION__);
972 goto ERR_EXIT;
973 }
974 }
975 else
976 {
977 yl = yc = 0;
978 }
979
980 while (dinfo.output_scanline < dinfo.output_height)
981 {
982 jpeg_read_raw_data(&dinfo, scanarray, 16);
983
984 for (y = 0; y < 8 * vsf[0]; yl += numfields, y++)
985 {
986 xd = yl * width;
987 xs = xsl;
988
989 if (hdown == 0) // no horiz downsampling
990 {
991 for (x = 0; x < width; x++)
992 raw0[xd++] = row0[y][xs++];
993 }
994 else if (hdown == 1) // half the res
995 {
996 for (x = 0; x < width; x++, xs += 2)
997 raw0[xd++] = (row0[y][xs] + row0[y][xs + 1]) >> 1;
998 }
999 else // 2:3 downsampling
1000 {
1001 for (x = 0; x < width / 2; x++, xd += 2, xs += 3)
1002 {
1003 raw0[xd] = (2 * row0[y][xs] + row0[y][xs + 1]) / 3;
1004 raw0[xd + 1] = (2 * row0[y][xs + 2] + row0[y][xs + 1]) / 3;
1005 }
1006 }
1007 }
1008
1009 for (y = 0; y < 8; y++)
1010 {
1011 xs = xsc;
1012
1013 if (hdown == 0)
1014 {
1015 for (x = 0; x < width / 2; x++, xs++)
1016 {
1017 chr1[y][x] = 0; //row1[y][xs];
1018 chr2[y][x] = 0; //row2[y][xs];
1019 }
1020 }
1021 else if (hdown == 1)
1022 {
1023 for (x = 0; x < width / 2; x++, xs += 2)
1024 {
1025 chr1[y][x] = 0; //(row1[y][xs] + row1[y][xs + 1]) >> 1;
1026 chr2[y][x] = 0; //(row2[y][xs] + row2[y][xs + 1]) >> 1;
1027 }
1028 }
1029 else
1030 {
1031 for (x = 0; x < width / 2; x += 2, xs += 3)
1032 {
1033 chr1[y][x] = 0; //(2 * row1[y][xs] + row1[y][xs + 1]) / 3;
1034 chr1[y][x + 1] = 0;
1035 //(2 * row1[y][xs + 2] + row1[y][xs + 1]) / 3;
1036 chr2[y][x] = 0; // (2 * row2[y][xs] + row2[y][xs + 1]) / 3;
1037 chr2[y][x + 1] = 0;
1038 //(2 * row2[y][xs + 2] + row2[y][xs + 1]) / 3;
1039 }
1040 }
1041 }
1042
1043 switch (ctype)
1044 {
1045 case Y4M_CHROMA_422:
1046 if (vsf[0] == 1)
1047 {
1048 /* Just copy */
1049 for (y = 0; y < 8 /*&& yc < height */; y++, yc += numfields)
1050 {
1051 xd = yc * width / 2;
1052
1053 for (x = 0; x < width / 2; x++, xd++)
1054 {
1055 raw1[xd] = 127; //chr1[y][x];
1056 raw2[xd] = 127; //chr2[y][x];
1057 }
1058 }
1059 }
1060 else
1061 {
1062 /* upsample */
1063 for (y = 0; y < 8 /*&& yc < height */; y++)
1064 {
1065 xd = yc * width / 2;
1066
1067 for (x = 0; x < width / 2; x++, xd++)
1068 {
1069 raw1[xd] = 127; //chr1[y][x];
1070 raw2[xd] = 127; //chr2[y][x];
1071 }
1072
1073 yc += numfields;
1074 xd = yc * width / 2;
1075
1076 for (x = 0; x < width / 2; x++, xd++)
1077 {
1078 raw1[xd] = 127; //chr1[y][x];
1079 raw2[xd] = 127; //chr2[y][x];
1080 }
1081
1082 yc += numfields;
1083 }
1084 }
1085 break;
1086 /*
1087 * should be case Y4M_CHROMA_420JPEG: but use default: for compatibility. Some
1088 * pass things like '420' in with the expectation that anything other than
1089 * Y4M_CHROMA_422 will default to 420JPEG.
1090 */
1091 default:
1092 if (vsf[0] == 1)
1093 {
1094 /* Really downsample */
1095 for (y = 0; y < 8; y += 2, yc += numfields)
1096 {
1097 xd = yc * width / 2;
1098
1099 for (x = 0; x < width / 2; x++, xd++)
1100 {
1101 raw1[xd] = 127; //(chr1[y][x] + chr1[y + 1][x]) >> 1;
1102 raw2[xd] = 127; //(chr2[y][x] + chr2[y + 1][x]) >> 1;
1103 }
1104 }
1105 }
1106 else
1107 {
1108 /* Just copy */
1109
1110 for (y = 0; y < 8; y++, yc += numfields)
1111 {
1112 xd = yc * width / 2;
1113
1114 for (x = 0; x < width / 2; x++, xd++)
1115 {
1116 raw1[xd] = 127; //chr1[y][x];
1117 raw2[xd] = 127; //chr2[y][x];
1118 }
1119 }
1120 }
1121 break;
1122 }
1123 }
1124
1125 (void)jpeg_finish_decompress(&dinfo);
1126
1127 if (field == 0 && numfields > 1)
1128 jpeg_skip_ff(&dinfo);
1129 }
1130
1131 jpeg_destroy_decompress(&dinfo);
1132 return 0;
1133
1134ERR_EXIT:
1135 jpeg_destroy_decompress(&dinfo);
1136 return -1;
1137}
1138
1139/*******************************************************************
1140 * *
1141 * encode_jpeg_data: Compress raw YCbCr data (output JPEG *
1142 * may be interlaced *
1143 * *
1144 *******************************************************************/
1145
1146/*
1147* jpeg_data: Buffer to hold output jpeg
1148* len: Length of buffer
1149* itype: 0: Not interlaced
1150* 1: Interlaced, Top field first
1151* 2: Interlaced, Bottom field first
1152* ctype Chroma format for decompression.
1153* Currently only Y4M_CHROMA_{420JPEG,422} are available
1154*/
1155
1156int encode_jpeg_raw(unsigned char *jpeg_data, int len, int quality, int itype, int ctype, unsigned int width,
1157 unsigned int height, unsigned char *raw0, unsigned char *raw1, unsigned char *raw2)
1158{
1159 int numfields, field, yl, yc, y, i;
1160
1161 JSAMPROW row0[16] = { buf0[0], buf0[1], buf0[2], buf0[3], buf0[4], buf0[5], buf0[6], buf0[7],
1162 buf0[8], buf0[9], buf0[10], buf0[11], buf0[12], buf0[13], buf0[14], buf0[15] };
1163
1164 JSAMPROW row1[8] = { buf1[0], buf1[1], buf1[2], buf1[3], buf1[4], buf1[5], buf1[6], buf1[7] };
1165
1166 JSAMPROW row2[8] = { buf2[0], buf2[1], buf2[2], buf2[3], buf2[4], buf2[5], buf2[6], buf2[7] };
1167
1168 JSAMPARRAY scanarray[3] = { row0, row1, row2 };
1169
1170 struct jpeg_compress_struct cinfo;
1171 struct my_error_mgr jerr;
1172
1173 /* We set up the normal JPEG error routines, then override error_exit. */
1174 cinfo.err = jpeg_std_error(&jerr.pub);
1175 jerr.pub.error_exit = my_error_exit;
1176
1177 /* Establish the setjmp return context for my_error_exit to use. */
1178 if (setjmp(jerr.setjmp_buffer))
1179 {
1180 /* If we get here, the JPEG code has signaled an error. */
1181 jpeg_destroy_compress(&cinfo);
1182 return -1;
1183 }
1184
1185 jpeg_create_compress(&cinfo);
1186
1187 jpeg_buffer_dest(&cinfo, jpeg_data, len);
1188
1189 /* Set some jpeg header fields */
1190
1191 cinfo.input_components = 3;
1192 jpeg_set_defaults(&cinfo);
1193 jpeg_set_quality(&cinfo, quality, FALSE);
1194
1195 cinfo.raw_data_in = TRUE;
1196 cinfo.in_color_space = JCS_YCbCr;
1197 cinfo.dct_method = JDCT_IFAST;
1198
1199 cinfo.input_gamma = 1.0;
1200
1201 cinfo.comp_info[0].h_samp_factor = 2;
1202 cinfo.comp_info[0].v_samp_factor = 1; /*1||2 */
1203 cinfo.comp_info[1].h_samp_factor = 1;
1204 cinfo.comp_info[1].v_samp_factor = 1;
1205 cinfo.comp_info[2].h_samp_factor = 1; /*1||2 */
1206 cinfo.comp_info[2].v_samp_factor = 1;
1207
1208 if ((width > 4096) || (height > 4096))
1209 {
1210 fprintf(stderr,
1211 "%s: Image dimensions (%dx%d) exceed lavtools' max "
1212 "(4096x4096)",
1213 __FUNCTION__, width, height);
1214 goto ERR_EXIT;
1215 }
1216
1217 if ((width % 16) || (height % 16))
1218 {
1219 fprintf(stderr, "%s: Image dimensions (%dx%d) not multiples of 16", __FUNCTION__, width, height);
1220 goto ERR_EXIT;
1221 }
1222
1223 cinfo.image_width = width;
1224
1225 switch (itype)
1226 {
1228 case Y4M_ILACE_BOTTOM_FIRST: /* interlaced */
1229 numfields = 2;
1230 break;
1231 default:
1232 numfields = 1;
1233 if (height > 2048)
1234 {
1235 fprintf(stderr,
1236 "%s: Image height (%d) exceeds lavtools max "
1237 "for non-interlaced frames",
1238 __FUNCTION__, height);
1239 goto ERR_EXIT;
1240 }
1241 }
1242
1243 cinfo.image_height = height / numfields;
1244
1245 yl = yc = 0; /* y luma, chroma */
1246
1247 for (field = 0; field < numfields; field++)
1248 {
1249 jpeg_start_compress(&cinfo, FALSE);
1250
1251 if (numfields == 2)
1252 {
1253 static const JOCTET marker0[40];
1254
1255 jpeg_write_marker(&cinfo, JPEG_APP0, marker0, 14);
1256 jpeg_write_marker(&cinfo, JPEG_APP0 + 1, marker0, 40);
1257
1258 switch (itype)
1259 {
1260 case Y4M_ILACE_TOP_FIRST: /* top field first */
1261 yl = yc = field;
1262 break;
1263 case Y4M_ILACE_BOTTOM_FIRST: /* bottom field first */
1264 yl = yc = (1 - field);
1265 break;
1266 default:
1267 fprintf(stderr, "%s: Input is interlaced but no interlacing set", __FUNCTION__);
1268 goto ERR_EXIT;
1269 }
1270 }
1271 else
1272 {
1273 yl = yc = 0;
1274 }
1275
1276 while (cinfo.next_scanline < cinfo.image_height)
1277 {
1278 for (y = 0; y < 8 * cinfo.comp_info[0].v_samp_factor; yl += numfields, y++)
1279 {
1280 row0[y] = &raw0[yl * width];
1281 }
1282
1283 for (y = 0; y < 8; y++)
1284 {
1285 row1[y] = &raw1[yc * width / 2];
1286 row2[y] = &raw2[yc * width / 2];
1287
1288 if ((ctype == Y4M_CHROMA_422) || (y % 2))
1289 yc += numfields;
1290 }
1291
1292 jpeg_write_raw_data(&cinfo, scanarray, 8 * cinfo.comp_info[0].v_samp_factor);
1293 }
1294
1295 (void)jpeg_finish_compress(&cinfo);
1296 }
1297
1298 /* FIXME */
1299 i = len - cinfo.dest->free_in_buffer;
1300
1301 jpeg_destroy_compress(&cinfo);
1302 return i; /* size of jpeg */
1303
1304ERR_EXIT:
1305 jpeg_destroy_compress(&cinfo);
1306 return -1;
1307}
1308
1309int decode_jpeg_rgb(unsigned char *inBuffer, unsigned long inSize, uint8_t **memptr, size_t *memsize, int *naxis, int *w, int *h)
1310{
1311 /* these are standard libjpeg structures for reading(decompression) */
1312 struct jpeg_decompress_struct cinfo;
1313 struct jpeg_error_mgr jerr;
1314 /* libjpeg data structure for storing one row, that is, scanline of an image */
1315 JSAMPROW row_pointer[1] = { NULL };
1316
1317 /* here we set up the standard libjpeg error handler */
1318 cinfo.err = jpeg_std_error(&jerr);
1319 /* setup decompression process and source, then read JPEG header */
1320 jpeg_create_decompress(&cinfo);
1321 /* this makes the library read from infile */
1322 jpeg_mem_src(&cinfo, inBuffer, inSize);
1323
1324 /* reading the image header which contains image information */
1325 jpeg_read_header(&cinfo, (boolean)TRUE);
1326
1327 /* Start decompression jpeg here */
1328 jpeg_start_decompress(&cinfo);
1329
1330 *memsize = cinfo.output_width * cinfo.output_height * cinfo.num_components;
1331 *memptr = (uint8_t *)realloc(*memptr, *memsize);
1332
1333 uint8_t *destmem = *memptr;
1334
1335 *naxis = cinfo.num_components;
1336 *w = cinfo.output_width;
1337 *h = cinfo.output_height;
1338
1339 /* now actually read the jpeg into the raw buffer */
1340 row_pointer[0] = (unsigned char *)malloc(cinfo.output_width * cinfo.num_components);
1341
1342 /* read one scan line at a time */
1343 for (unsigned int row = 0; row < cinfo.image_height; row++)
1344 {
1345 unsigned char *ppm8 = row_pointer[0];
1346 jpeg_read_scanlines(&cinfo, row_pointer, 1);
1347 memcpy(destmem, ppm8, cinfo.output_width * cinfo.num_components);
1348 destmem += cinfo.output_width * cinfo.num_components;
1349 }
1350
1351 /* wrap up decompression, destroy objects, free pointers and close open files */
1352 jpeg_finish_decompress(&cinfo);
1353 jpeg_destroy_decompress(&cinfo);
1354
1355 if (row_pointer[0])
1356 free(row_pointer[0]);
1357
1358 return 0;
1359}
int encode_jpeg_raw(unsigned char *jpeg_data, int len, int quality, int itype, int ctype, unsigned int width, unsigned int height, unsigned char *raw0, unsigned char *raw1, unsigned char *raw2)
encode raw JPEG buffer
Definition jpegutils.c:1156
#define MAX_CHROMA_WIDTH
Definition jpegutils.c:292
int decode_jpeg_raw(unsigned char *jpeg_data, int len, int itype, int ctype, unsigned int width, unsigned int height, unsigned char *raw0, unsigned char *raw1, unsigned char *raw2)
decode JPEG buffer
Definition jpegutils.c:461
int decode_jpeg_rgb(unsigned char *inBuffer, unsigned long inSize, uint8_t **memptr, size_t *memsize, int *naxis, int *w, int *h)
decode_jpeg_rgb Read jpeg in memory buffer and produce RGB image
Definition jpegutils.c:1309
#define MAX_LUMA_WIDTH
Definition jpegutils.c:291
int decode_jpeg_gray_raw(unsigned char *jpeg_data, int len, int itype, int ctype, unsigned int width, unsigned int height, unsigned char *raw0, unsigned char *raw1, unsigned char *raw2)
decode JPEG raw gray buffer
Definition jpegutils.c:837
#define Y4M_ILACE_TOP_FIRST
Definition jpegutils.h:37
#define Y4M_ILACE_BOTTOM_FIRST
Definition jpegutils.h:38
#define Y4M_CHROMA_422
Definition jpegutils.h:45
JMETHOD(void, original_emit_message,(j_common_ptr cinfo, int msg_level))
jmp_buf setjmp_buffer
Definition jpegutils.c:258
struct jpeg_error_mgr pub
Definition jpegutils.c:257
#define TRUE
Definition stvdriver.c:54
#define FALSE
Definition stvdriver.c:53