Instrument Neutral Distributed Interface INDI  1.9.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 <Rainer@Johanni.de>
6  * Copyright (C) 2001 pHilipp Zabel <pzabel@gmx.de>
7  * Copyright (C) 2008 Angel Carpintero <ack@telefonica.net>
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 
53 static void jpeg_buffer_src(j_decompress_ptr cinfo, unsigned char *buffer, long num);
54 static void jpeg_buffer_dest(j_compress_ptr cinfo, unsigned char *buffer, long len);
55 static 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 
70 static 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 allready provided.
80  * Is nevertheless sometimes called - sets the input buffer to data
81  * which is the JPEG EOI marker;
82  *
83  */
84 
85 static uint8_t EOI_data[2] = { 0xFF, 0xD9 };
86 
87 static 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 
100 static 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 
116 static 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 
126 static 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 beetween images.
154  */
155 
156 static 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 
179 static 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 
193 static 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 
208 static 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 
220 static 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 */
263  int warning_seen;
264 };
265 
266 static 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 
279 static 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 
294 static unsigned char buf0[16][MAX_LUMA_WIDTH];
295 static unsigned char buf1[8][MAX_CHROMA_WIDTH];
296 static unsigned char buf2[8][MAX_CHROMA_WIDTH];
297 static unsigned char chr1[8][MAX_CHROMA_WIDTH];
298 static unsigned char chr2[8][MAX_CHROMA_WIDTH];
299 
300 #if 1 /* generation of 'std' Huffman tables... */
301 
302 static 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 
328 static 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 
434 static 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 
461 int 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  {
629  case Y4M_ILACE_TOP_FIRST:
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 
822 ERR_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 
837 int 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  {
964  case Y4M_ILACE_TOP_FIRST:
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 
1134 ERR_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 
1156 int 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  {
1227  case Y4M_ILACE_TOP_FIRST:
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 
1304 ERR_EXIT:
1305  jpeg_destroy_compress(&cinfo);
1306  return -1;
1307 }
1308 
1309 int 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 }
MAX_CHROMA_WIDTH
#define MAX_CHROMA_WIDTH
Definition: jpegutils.c:292
encode_jpeg_raw
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
Y4M_CHROMA_422
#define Y4M_CHROMA_422
Definition: jpegutils.h:45
my_error_mgr::JMETHOD
JMETHOD(void, original_emit_message,(j_common_ptr cinfo, int msg_level))
TRUE
#define TRUE
Definition: stvdriver.c:54
MAX_LUMA_WIDTH
#define MAX_LUMA_WIDTH
Definition: jpegutils.c:291
my_error_mgr
Definition: jpegutils.c:255
decode_jpeg_raw
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
my_error_mgr::warning_seen
int warning_seen
Definition: jpegutils.c:267
my_error_mgr::setjmp_buffer
jmp_buf setjmp_buffer
Definition: jpegutils.c:262
decode_jpeg_rgb
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
my_error_mgr::pub
struct jpeg_error_mgr pub
Definition: jpegutils.c:261
Y4M_ILACE_BOTTOM_FIRST
#define Y4M_ILACE_BOTTOM_FIRST
Definition: jpegutils.h:38
jpegutils.h
FALSE
#define FALSE
Definition: stvdriver.c:53
decode_jpeg_gray_raw
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
Y4M_ILACE_TOP_FIRST
#define Y4M_ILACE_TOP_FIRST
Definition: jpegutils.h:37
Aux::buffer
std::vector< uint8_t > buffer
Definition: celestronauxpacket.h:38