home *** CD-ROM | disk | FTP | other *** search
/ Photo CD Demo 1 / Demo.bin / compresn / jpegv3sr / jrdjfif.c < prev    next >
C/C++ Source or Header  |  1992-01-17  |  19KB  |  741 lines

  1. /*
  2.  * jrdjfif.c
  3.  *
  4.  * Copyright (C) 1991, 1992, Thomas G. Lane.
  5.  * This file is part of the Independent JPEG Group's software.
  6.  * For conditions of distribution and use, see the accompanying README file.
  7.  *
  8.  * This file contains routines to decode standard JPEG file headers/markers.
  9.  * This code will handle "raw JPEG" and JFIF-convention JPEG files.
  10.  *
  11.  * You can also use this module to decode a raw-JPEG or JFIF-standard data
  12.  * stream that is embedded within a larger file.  To do that, you must
  13.  * position the file to the JPEG SOI marker (0xFF/0xD8) that begins the
  14.  * data sequence to be decoded.  If nothing better is possible, you can scan
  15.  * the file until you see the SOI marker, then use JUNGETC to push it back.
  16.  *
  17.  * This module relies on the JGETC macro and the read_jpeg_data method (which
  18.  * is provided by the user interface) to read from the JPEG data stream.
  19.  * Therefore, this module is not dependent on any particular assumption about
  20.  * the data source; it need not be a stdio stream at all.  (This fact does
  21.  * NOT carry over to more complex JPEG file formats such as JPEG-in-TIFF;
  22.  * those format control modules may well need to assume stdio input.)
  23.  *
  24.  * These routines are invoked via the methods read_file_header,
  25.  * read_scan_header, read_jpeg_data, read_scan_trailer, and read_file_trailer.
  26.  */
  27.  
  28. #include "jinclude.h"
  29.  
  30. #ifdef JFIF_SUPPORTED
  31.  
  32.  
  33. typedef enum {            /* JPEG marker codes */
  34.   M_SOF0  = 0xc0,
  35.   M_SOF1  = 0xc1,
  36.   M_SOF2  = 0xc2,
  37.   M_SOF3  = 0xc3,
  38.   
  39.   M_SOF5  = 0xc5,
  40.   M_SOF6  = 0xc6,
  41.   M_SOF7  = 0xc7,
  42.   
  43.   M_JPG   = 0xc8,
  44.   M_SOF9  = 0xc9,
  45.   M_SOF10 = 0xca,
  46.   M_SOF11 = 0xcb,
  47.   
  48.   M_SOF13 = 0xcd,
  49.   M_SOF14 = 0xce,
  50.   M_SOF15 = 0xcf,
  51.   
  52.   M_DHT   = 0xc4,
  53.   
  54.   M_DAC   = 0xcc,
  55.   
  56.   M_RST0  = 0xd0,
  57.   M_RST1  = 0xd1,
  58.   M_RST2  = 0xd2,
  59.   M_RST3  = 0xd3,
  60.   M_RST4  = 0xd4,
  61.   M_RST5  = 0xd5,
  62.   M_RST6  = 0xd6,
  63.   M_RST7  = 0xd7,
  64.   
  65.   M_SOI   = 0xd8,
  66.   M_EOI   = 0xd9,
  67.   M_SOS   = 0xda,
  68.   M_DQT   = 0xdb,
  69.   M_DNL   = 0xdc,
  70.   M_DRI   = 0xdd,
  71.   M_DHP   = 0xde,
  72.   M_EXP   = 0xdf,
  73.   
  74.   M_APP0  = 0xe0,
  75.   M_APP15 = 0xef,
  76.   
  77.   M_JPG0  = 0xf0,
  78.   M_JPG13 = 0xfd,
  79.   M_COM   = 0xfe,
  80.   
  81.   M_TEM   = 0x01,
  82.   
  83.   M_ERROR = 0x100
  84. } JPEG_MARKER;
  85.  
  86.  
  87. /*
  88.  * Reload the input buffer after it's been emptied, and return the next byte.
  89.  * This is exported for direct use by the entropy decoder.
  90.  * See the JGETC macro for calling conditions.
  91.  *
  92.  * For this header control module, read_jpeg_data is supplied by the
  93.  * user interface.  However, header formats that require random access
  94.  * to the input file would need to supply their own code.  This code is
  95.  * left here to indicate what is required.
  96.  */
  97.  
  98. #if 0                /* not needed in this module */
  99.  
  100. METHODDEF int
  101. read_jpeg_data (decompress_info_ptr cinfo)
  102. {
  103.   cinfo->next_input_byte = cinfo->input_buffer + MIN_UNGET;
  104.  
  105.   cinfo->bytes_in_buffer = (int) JFREAD(cinfo->input_file,
  106.                     cinfo->next_input_byte,
  107.                     JPEG_BUF_SIZE);
  108.   
  109.   if (cinfo->bytes_in_buffer <= 0)
  110.     ERREXIT(cinfo->emethods, "Unexpected EOF in JPEG file");
  111.  
  112.   return JGETC(cinfo);
  113. }
  114.  
  115. #endif
  116.  
  117.  
  118. /*
  119.  * Routines to parse JPEG markers & save away the useful info.
  120.  */
  121.  
  122.  
  123. LOCAL INT32
  124. get_2bytes (decompress_info_ptr cinfo)
  125. /* Get a 2-byte unsigned integer (e.g., a marker parameter length field) */
  126. {
  127.   INT32 a;
  128.   
  129.   a = JGETC(cinfo);
  130.   return (a << 8) + JGETC(cinfo);
  131. }
  132.  
  133.  
  134. LOCAL void
  135. skip_variable (decompress_info_ptr cinfo, int code)
  136. /* Skip over an unknown or uninteresting variable-length marker */
  137. {
  138.   INT32 length;
  139.   
  140.   length = get_2bytes(cinfo);
  141.   
  142.   TRACEMS2(cinfo->emethods, 1,
  143.        "Skipping marker 0x%02x, length %u", code, (int) length);
  144.   
  145.   for (length -= 2; length > 0; length--)
  146.     (void) JGETC(cinfo);
  147. }
  148.  
  149.  
  150. LOCAL void
  151. get_dht (decompress_info_ptr cinfo)
  152. /* Process a DHT marker */
  153. {
  154.   INT32 length;
  155.   UINT8 bits[17];
  156.   UINT8 huffval[256];
  157.   int i, index, count;
  158.   HUFF_TBL **htblptr;
  159.   
  160.   length = get_2bytes(cinfo)-2;
  161.   
  162.   while (length > 0) {
  163.     index = JGETC(cinfo);
  164.  
  165.     TRACEMS1(cinfo->emethods, 1, "Define Huffman Table 0x%02x", index);
  166.       
  167.     bits[0] = 0;
  168.     count = 0;
  169.     for (i = 1; i <= 16; i++) {
  170.       bits[i] = (UINT8) JGETC(cinfo);
  171.       count += bits[i];
  172.     }
  173.  
  174.     TRACEMS8(cinfo->emethods, 2, "        %3d %3d %3d %3d %3d %3d %3d %3d",
  175.          bits[1], bits[2], bits[3], bits[4],
  176.          bits[5], bits[6], bits[7], bits[8]);
  177.     TRACEMS8(cinfo->emethods, 2, "        %3d %3d %3d %3d %3d %3d %3d %3d",
  178.          bits[9], bits[10], bits[11], bits[12],
  179.          bits[13], bits[14], bits[15], bits[16]);
  180.  
  181.     if (count > 256)
  182.       ERREXIT(cinfo->emethods, "Bogus DHT counts");
  183.  
  184.     for (i = 0; i < count; i++)
  185.       huffval[i] = (UINT8) JGETC(cinfo);
  186.  
  187.     length -= 1 + 16 + count;
  188.  
  189.     if (index & 0x10) {        /* AC table definition */
  190.       index -= 0x10;
  191.       htblptr = &cinfo->ac_huff_tbl_ptrs[index];
  192.     } else {            /* DC table definition */
  193.       htblptr = &cinfo->dc_huff_tbl_ptrs[index];
  194.     }
  195.  
  196.     if (index < 0 || index >= NUM_HUFF_TBLS)
  197.       ERREXIT1(cinfo->emethods, "Bogus DHT index %d", index);
  198.  
  199.     if (*htblptr == NULL)
  200.       *htblptr = (HUFF_TBL *) (*cinfo->emethods->alloc_small) (SIZEOF(HUFF_TBL));
  201.   
  202.     memcpy((void *) (*htblptr)->bits, (void *) bits,
  203.        SIZEOF((*htblptr)->bits));
  204.     memcpy((void *) (*htblptr)->huffval, (void *) huffval,
  205.        SIZEOF((*htblptr)->huffval));
  206.     }
  207. }
  208.  
  209.  
  210. LOCAL void
  211. get_dac (decompress_info_ptr cinfo)
  212. /* Process a DAC marker */
  213. {
  214.   INT32 length;
  215.   int index, val;
  216.  
  217.   length = get_2bytes(cinfo)-2;
  218.   
  219.   while (length > 0) {
  220.     index = JGETC(cinfo);
  221.     val = JGETC(cinfo);
  222.  
  223.     TRACEMS2(cinfo->emethods, 1,
  224.          "Define Arithmetic Table 0x%02x: 0x%02x", index, val);
  225.  
  226.     if (index < 0 || index >= (2*NUM_ARITH_TBLS))
  227.       ERREXIT1(cinfo->emethods, "Bogus DAC index %d", index);
  228.  
  229.     if (index >= NUM_ARITH_TBLS) { /* define AC table */
  230.       cinfo->arith_ac_K[index-NUM_ARITH_TBLS] = (UINT8) val;
  231.     } else {            /* define DC table */
  232.       cinfo->arith_dc_L[index] = (UINT8) (val & 0x0F);
  233.       cinfo->arith_dc_U[index] = (UINT8) (val >> 4);
  234.       if (cinfo->arith_dc_L[index] > cinfo->arith_dc_U[index])
  235.     ERREXIT1(cinfo->emethods, "Bogus DAC value 0x%x", val);
  236.     }
  237.  
  238.     length -= 2;
  239.   }
  240. }
  241.  
  242.  
  243. LOCAL void
  244. get_dqt (decompress_info_ptr cinfo)
  245. /* Process a DQT marker */
  246. {
  247.   INT32 length;
  248.   int n, i, prec;
  249.   UINT16 tmp;
  250.   QUANT_TBL_PTR quant_ptr;
  251.   
  252.   length = get_2bytes(cinfo) - 2;
  253.   
  254.   while (length > 0) {
  255.     n = JGETC(cinfo);
  256.     prec = n >> 4;
  257.     n &= 0x0F;
  258.  
  259.     TRACEMS2(cinfo->emethods, 1,
  260.          "Define Quantization Table %d  precision %d", n, prec);
  261.  
  262.     if (n >= NUM_QUANT_TBLS)
  263.       ERREXIT1(cinfo->emethods, "Bogus table number %d", n);
  264.       
  265.     if (cinfo->quant_tbl_ptrs[n] == NULL)
  266.       cinfo->quant_tbl_ptrs[n] = (QUANT_TBL_PTR)
  267.     (*cinfo->emethods->alloc_small) (SIZEOF(QUANT_TBL));
  268.     quant_ptr = cinfo->quant_tbl_ptrs[n];
  269.  
  270.     for (i = 0; i < DCTSIZE2; i++) {
  271.       tmp = JGETC(cinfo);
  272.       if (prec)
  273.     tmp = (tmp<<8) + JGETC(cinfo);
  274.       quant_ptr[i] = tmp;
  275.     }
  276.  
  277.     for (i = 0; i < DCTSIZE2; i += 8) {
  278.       TRACEMS8(cinfo->emethods, 2, "        %4d %4d %4d %4d %4d %4d %4d %4d",
  279.            quant_ptr[i  ], quant_ptr[i+1], quant_ptr[i+2], quant_ptr[i+3],
  280.            quant_ptr[i+4], quant_ptr[i+5], quant_ptr[i+6], quant_ptr[i+7]);
  281.     }
  282.  
  283.     length -= DCTSIZE2+1;
  284.     if (prec) length -= DCTSIZE2;
  285.   }
  286. }
  287.  
  288.  
  289. LOCAL void
  290. get_dri (decompress_info_ptr cinfo)
  291. /* Process a DRI marker */
  292. {
  293.   if (get_2bytes(cinfo) != 4)
  294.     ERREXIT(cinfo->emethods, "Bogus length in DRI");
  295.  
  296.   cinfo->restart_interval = (UINT16) get_2bytes(cinfo);
  297.  
  298.   TRACEMS1(cinfo->emethods, 1,
  299.        "Define Restart Interval %d", cinfo->restart_interval);
  300. }
  301.  
  302.  
  303. LOCAL void
  304. get_app0 (decompress_info_ptr cinfo)
  305. /* Process an APP0 marker */
  306. {
  307. #define JFIF_LEN 14
  308.   INT32 length;
  309.   UINT8 b[JFIF_LEN];
  310.   int buffp;
  311.  
  312.   length = get_2bytes(cinfo) - 2;
  313.  
  314.   /* See if a JFIF APP0 marker is present */
  315.  
  316.   if (length >= JFIF_LEN) {
  317.     for (buffp = 0; buffp < JFIF_LEN; buffp++)
  318.       b[buffp] = (UINT8) JGETC(cinfo);
  319.     length -= JFIF_LEN;
  320.  
  321.     if (b[0]=='J' && b[1]=='F' && b[2]=='I' && b[3]=='F' && b[4]==0) {
  322.       /* Found JFIF APP0 marker: check version */
  323.       /* Major version must be 1 */
  324.       if (b[5] != 1)
  325.     ERREXIT2(cinfo->emethods, "Unsupported JFIF revision number %d.%02d",
  326.          b[5], b[6]);
  327.       /* Minor version should be 0 or 1, but try to process anyway if newer */
  328.       if (b[6] != 0 && b[6] != 1)
  329.     TRACEMS2(cinfo->emethods, 0, "Warning: unknown JFIF revision number %d.%02d",
  330.          b[5], b[6]);
  331.       /* Save info */
  332.       cinfo->density_unit = b[7];
  333.       cinfo->X_density = (b[8] << 8) + b[9];
  334.       cinfo->Y_density = (b[10] << 8) + b[11];
  335.       /* Assume colorspace is YCbCr, unless UI has overridden me */
  336.       if (cinfo->jpeg_color_space == CS_UNKNOWN)
  337.     cinfo->jpeg_color_space = CS_YCbCr;
  338.       TRACEMS3(cinfo->emethods, 1, "JFIF APP0 marker, density %dx%d  %d",
  339.            cinfo->X_density, cinfo->Y_density, cinfo->density_unit);
  340.     } else {
  341.       TRACEMS(cinfo->emethods, 1, "Unknown APP0 marker (not JFIF)");
  342.     }
  343.   } else {
  344.     TRACEMS1(cinfo->emethods, 1,
  345.          "Short APP0 marker, length %d", (int) length);
  346.   }
  347.  
  348.   while (length-- > 0)        /* skip any remaining data */
  349.     (void) JGETC(cinfo);
  350. }
  351.  
  352.  
  353. LOCAL void
  354. get_sof (decompress_info_ptr cinfo, int code)
  355. /* Process a SOFn marker */
  356. {
  357.   INT32 length;
  358.   short ci;
  359.   int c;
  360.   jpeg_component_info * compptr;
  361.   
  362.   length = get_2bytes(cinfo);
  363.   
  364.   cinfo->data_precision = JGETC(cinfo);
  365.   cinfo->image_height   = get_2bytes(cinfo);
  366.   cinfo->image_width    = get_2bytes(cinfo);
  367.   cinfo->num_components = JGETC(cinfo);
  368.  
  369.   TRACEMS4(cinfo->emethods, 1,
  370.        "Start Of Frame 0x%02x: width=%u, height=%u, components=%d",
  371.        code, (int) cinfo->image_width, (int) cinfo->image_height,
  372.        cinfo->num_components);
  373.  
  374.   /* We don't support files in which the image height is initially specified */
  375.   /* as 0 and is later redefined by DNL.  As long as we have to check that,  */
  376.   /* might as well have a general sanity check. */
  377.   if (cinfo->image_height <= 0 || cinfo->image_width <= 0
  378.       || cinfo->num_components <= 0)
  379.     ERREXIT(cinfo->emethods, "Empty JPEG image (DNL not supported)");
  380.  
  381. #ifdef EIGHT_BIT_SAMPLES
  382.   if (cinfo->data_precision != 8)
  383.     ERREXIT(cinfo->emethods, "Unsupported JPEG data precision");
  384. #endif
  385. #ifdef TWELVE_BIT_SAMPLES
  386.   if (cinfo->data_precision != 12) /* this needs more thought?? */
  387.     ERREXIT(cinfo->emethods, "Unsupported JPEG data precision");
  388. #endif
  389. #ifdef SIXTEEN_BIT_SAMPLES
  390.   if (cinfo->data_precision != 16) /* this needs more thought?? */
  391.     ERREXIT(cinfo->emethods, "Unsupported JPEG data precision");
  392. #endif
  393.  
  394.   if (length != (cinfo->num_components * 3 + 8))
  395.     ERREXIT(cinfo->emethods, "Bogus SOF length");
  396.  
  397.   cinfo->comp_info = (jpeg_component_info *) (*cinfo->emethods->alloc_small)
  398.             (cinfo->num_components * SIZEOF(jpeg_component_info));
  399.   
  400.   for (ci = 0; ci < cinfo->num_components; ci++) {
  401.     compptr = &cinfo->comp_info[ci];
  402.     compptr->component_index = ci;
  403.     compptr->component_id = JGETC(cinfo);
  404.     c = JGETC(cinfo);
  405.     compptr->h_samp_factor = (c >> 4) & 15;
  406.     compptr->v_samp_factor = (c     ) & 15;
  407.     compptr->quant_tbl_no  = JGETC(cinfo);
  408.       
  409.     TRACEMS4(cinfo->emethods, 1, "    Component %d: %dhx%dv q=%d",
  410.          compptr->component_id, compptr->h_samp_factor,
  411.          compptr->v_samp_factor, compptr->quant_tbl_no);
  412.   }
  413. }
  414.  
  415.  
  416. LOCAL void
  417. get_sos (decompress_info_ptr cinfo)
  418. /* Process a SOS marker */
  419. {
  420.   INT32 length;
  421.   int i, ci, n, c, cc;
  422.   jpeg_component_info * compptr;
  423.   
  424.   length = get_2bytes(cinfo);
  425.   
  426.   n = JGETC(cinfo);  /* Number of components */
  427.   cinfo->comps_in_scan = n;
  428.   length -= 3;
  429.   
  430.   if (length != (n * 2 + 3) || n < 1 || n > MAX_COMPS_IN_SCAN)
  431.     ERREXIT(cinfo->emethods, "Bogus SOS length");
  432.  
  433.   TRACEMS1(cinfo->emethods, 1, "Start Of Scan: %d components", n);
  434.   
  435.   for (i = 0; i < n; i++) {
  436.     cc = JGETC(cinfo);
  437.     c = JGETC(cinfo);
  438.     length -= 2;
  439.     
  440.     for (ci = 0; ci < cinfo->num_components; ci++)
  441.       if (cc == cinfo->comp_info[ci].component_id)
  442.     break;
  443.     
  444.     if (ci >= cinfo->num_components)
  445.       ERREXIT(cinfo->emethods, "Invalid component number in SOS");
  446.     
  447.     compptr = &cinfo->comp_info[ci];
  448.     cinfo->cur_comp_info[i] = compptr;
  449.     compptr->dc_tbl_no = (c >> 4) & 15;
  450.     compptr->ac_tbl_no = (c     ) & 15;
  451.     
  452.     TRACEMS3(cinfo->emethods, 1, "    c%d: [dc=%d ac=%d]", cc,
  453.          compptr->dc_tbl_no, compptr->ac_tbl_no);
  454.   }
  455.   
  456.   while (length > 0) {
  457.     (void) JGETC(cinfo);
  458.     length--;
  459.   }
  460. }
  461.  
  462.  
  463. LOCAL void
  464. get_soi (decompress_info_ptr cinfo)
  465. /* Process an SOI marker */
  466. {
  467.   int i;
  468.   
  469.   TRACEMS(cinfo->emethods, 1, "Start of Image");
  470.  
  471.   /* Reset all parameters that are defined to be reset by SOI */
  472.  
  473.   for (i = 0; i < NUM_ARITH_TBLS; i++) {
  474.     cinfo->arith_dc_L[i] = 0;
  475.     cinfo->arith_dc_U[i] = 1;
  476.     cinfo->arith_ac_K[i] = 5;
  477.   }
  478.   cinfo->restart_interval = 0;
  479.  
  480.   cinfo->density_unit = 0;    /* set default JFIF APP0 values */
  481.   cinfo->X_density = 1;
  482.   cinfo->Y_density = 1;
  483.  
  484.   cinfo->CCIR601_sampling = FALSE; /* Assume non-CCIR sampling */
  485. }
  486.  
  487.  
  488. LOCAL int
  489. next_marker (decompress_info_ptr cinfo)
  490. /* Find the next JPEG marker */
  491. /* Note that the output might not be a valid marker code, */
  492. /* but it will never be 0 or FF */
  493. {
  494.   int c, nbytes;
  495.  
  496.   nbytes = 0;
  497.   do {
  498.     do {            /* skip any non-FF bytes */
  499.       nbytes++;
  500.       c = JGETC(cinfo);
  501.     } while (c != 0xFF);
  502.     do {            /* skip any duplicate FFs */
  503.       nbytes++;
  504.       c = JGETC(cinfo);
  505.     } while (c == 0xFF);
  506.   } while (c == 0);        /* repeat if it was a stuffed FF/00 */
  507.  
  508.   if (nbytes != 2)
  509.     TRACEMS2(cinfo->emethods, 1, "Skipped %d bytes before marker 0x%02x",
  510.          nbytes-2, c);
  511.  
  512.   return c;
  513. }
  514.  
  515.  
  516. LOCAL JPEG_MARKER
  517. process_tables (decompress_info_ptr cinfo)
  518. /* Scan and process JPEG markers that can appear in any order */
  519. /* Return when an SOI, EOI, SOFn, or SOS is found */
  520. {
  521.   int c;
  522.  
  523.   while (TRUE) {
  524.     c = next_marker(cinfo);
  525.       
  526.     switch (c) {
  527.     case M_SOF0:
  528.     case M_SOF1:
  529.     case M_SOF2:
  530.     case M_SOF3:
  531.     case M_SOF5:
  532.     case M_SOF6:
  533.     case M_SOF7:
  534.     case M_JPG:
  535.     case M_SOF9:
  536.     case M_SOF10:
  537.     case M_SOF11:
  538.     case M_SOF13:
  539.     case M_SOF14:
  540.     case M_SOF15:
  541.     case M_SOI:
  542.     case M_EOI:
  543.     case M_SOS:
  544.       return ((JPEG_MARKER) c);
  545.       
  546.     case M_DHT:
  547.       get_dht(cinfo);
  548.       break;
  549.       
  550.     case M_DAC:
  551.       get_dac(cinfo);
  552.       break;
  553.       
  554.     case M_DQT:
  555.       get_dqt(cinfo);
  556.       break;
  557.       
  558.     case M_DRI:
  559.       get_dri(cinfo);
  560.       break;
  561.       
  562.     case M_APP0:
  563.       get_app0(cinfo);
  564.       break;
  565.  
  566.     case M_RST0:        /* these are all parameterless */
  567.     case M_RST1:
  568.     case M_RST2:
  569.     case M_RST3:
  570.     case M_RST4:
  571.     case M_RST5:
  572.     case M_RST6:
  573.     case M_RST7:
  574.     case M_TEM:
  575.       TRACEMS1(cinfo->emethods, 1, "Unexpected marker 0x%02x", c);
  576.       break;
  577.  
  578.     default:    /* must be DNL, DHP, EXP, APPn, JPGn, COM, or RESn */
  579.       skip_variable(cinfo, c);
  580.       break;
  581.     }
  582.   }
  583. }
  584.  
  585.  
  586.  
  587. /*
  588.  * Initialize and read the file header (everything through the SOF marker).
  589.  */
  590.  
  591. METHODDEF void
  592. read_file_header (decompress_info_ptr cinfo)
  593. {
  594.   int c;
  595.  
  596.   /* Demand an SOI marker at the start of the file --- otherwise it's
  597.    * probably not a JPEG file at all.  If the user interface wants to support
  598.    * nonstandard headers in front of the SOI, it must skip over them itself
  599.    * before calling jpeg_decompress().
  600.    */
  601.   if (JGETC(cinfo) != 0xFF  ||  JGETC(cinfo) != M_SOI)
  602.     ERREXIT(cinfo->emethods, "Not a JPEG file");
  603.  
  604.   get_soi(cinfo);        /* OK, process SOI */
  605.  
  606.   /* Process markers until SOF */
  607.   c = process_tables(cinfo);
  608.  
  609.   switch (c) {
  610.   case M_SOF0:
  611.   case M_SOF1:
  612.     get_sof(cinfo, c);
  613.     cinfo->arith_code = FALSE;
  614.     break;
  615.       
  616.   case M_SOF9:
  617.     get_sof(cinfo, c);
  618.     cinfo->arith_code = TRUE;
  619.     break;
  620.  
  621.   default:
  622.     ERREXIT1(cinfo->emethods, "Unsupported SOF marker type 0x%02x", c);
  623.     break;
  624.   }
  625.  
  626.   /* Figure out what colorspace we have */
  627.   /* (too bad the JPEG committee didn't provide a real way to specify this) */
  628.  
  629.   switch (cinfo->num_components) {
  630.   case 1:
  631.     cinfo->jpeg_color_space = CS_GRAYSCALE;
  632.     break;
  633.  
  634.   case 3:
  635.     /* if we saw a JFIF marker, leave it set to YCbCr; */
  636.     /* also leave it alone if UI has provided a value */
  637.     if (cinfo->jpeg_color_space == CS_UNKNOWN) {
  638.       short cid0 = cinfo->comp_info[0].component_id;
  639.       short cid1 = cinfo->comp_info[1].component_id;
  640.       short cid2 = cinfo->comp_info[2].component_id;
  641.  
  642.       if (cid0 == 1 && cid1 == 2 && cid2 == 3)
  643.     cinfo->jpeg_color_space = CS_YCbCr; /* assume it's JFIF w/out marker */
  644.       else if (cid0 == 1 && cid1 == 4 && cid2 == 5)
  645.     cinfo->jpeg_color_space = CS_YIQ; /* prototype's YIQ matrix */
  646.       else {
  647.     TRACEMS3(cinfo->emethods, 0,
  648.          "Unrecognized component IDs %d %d %d, assuming YCbCr",
  649.          cid0, cid1, cid2);
  650.     cinfo->jpeg_color_space = CS_YCbCr;
  651.       }
  652.     }
  653.     break;
  654.  
  655.   case 4:
  656.     cinfo->jpeg_color_space = CS_CMYK;
  657.     break;
  658.  
  659.   default:
  660.     cinfo->jpeg_color_space = CS_UNKNOWN;
  661.     break;
  662.   }
  663. }
  664.  
  665.  
  666. /*
  667.  * Read the start of a scan (everything through the SOS marker).
  668.  * Return TRUE if find SOS, FALSE if find EOI.
  669.  */
  670.  
  671. METHODDEF boolean
  672. read_scan_header (decompress_info_ptr cinfo)
  673. {
  674.   int c;
  675.   
  676.   /* Process markers until SOS or EOI */
  677.   c = process_tables(cinfo);
  678.   
  679.   switch (c) {
  680.   case M_SOS:
  681.     get_sos(cinfo);
  682.     return TRUE;
  683.     
  684.   case M_EOI:
  685.     TRACEMS(cinfo->emethods, 1, "End Of Image");
  686.     return FALSE;
  687.  
  688.   default:
  689.     ERREXIT1(cinfo->emethods, "Unexpected marker 0x%02x", c);
  690.     break;
  691.   }
  692.   return FALSE;            /* keeps lint happy */
  693. }
  694.  
  695.  
  696. /*
  697.  * Finish up after a compressed scan (series of read_jpeg_data calls);
  698.  * prepare for another read_scan_header call.
  699.  */
  700.  
  701. METHODDEF void
  702. read_scan_trailer (decompress_info_ptr cinfo)
  703. {
  704.   /* no work needed */
  705. }
  706.  
  707.  
  708. /*
  709.  * Finish up at the end of the file.
  710.  */
  711.  
  712. METHODDEF void
  713. read_file_trailer (decompress_info_ptr cinfo)
  714. {
  715.   /* no work needed */
  716. }
  717.  
  718.  
  719. /*
  720.  * The method selection routine for standard JPEG header reading.
  721.  * Note that this must be called by the user interface before calling
  722.  * jpeg_decompress.  When a non-JFIF file is to be decompressed (TIFF,
  723.  * perhaps), the user interface must discover the file type and call
  724.  * the appropriate method selection routine.
  725.  */
  726.  
  727. GLOBAL void
  728. jselrjfif (decompress_info_ptr cinfo)
  729. {
  730.   cinfo->methods->read_file_header = read_file_header;
  731.   cinfo->methods->read_scan_header = read_scan_header;
  732.   /* For JFIF/raw-JPEG format, the user interface supplies read_jpeg_data. */
  733. #if 0
  734.   cinfo->methods->read_jpeg_data = read_jpeg_data;
  735. #endif
  736.   cinfo->methods->read_scan_trailer = read_scan_trailer;
  737.   cinfo->methods->read_file_trailer = read_file_trailer;
  738. }
  739.  
  740. #endif /* JFIF_SUPPORTED */
  741.