DOOM-3-BFG

DOOM 3 BFG Edition
Log | Files | Refs

jcmarker.cpp (18449B)


      1 /*
      2  * jcmarker.c
      3  *
      4  * Copyright (C) 1991-1995, 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 write JPEG datastream markers.
      9  */
     10 
     11 #define JPEG_INTERNALS
     12 #include "jinclude.h"
     13 #include "jpeglib.h"
     14 
     15 
     16 typedef enum {          /* JPEG marker codes */
     17     M_SOF0  = 0xc0,
     18     M_SOF1  = 0xc1,
     19     M_SOF2  = 0xc2,
     20     M_SOF3  = 0xc3,
     21 
     22     M_SOF5  = 0xc5,
     23     M_SOF6  = 0xc6,
     24     M_SOF7  = 0xc7,
     25 
     26     M_JPG   = 0xc8,
     27     M_SOF9  = 0xc9,
     28     M_SOF10 = 0xca,
     29     M_SOF11 = 0xcb,
     30 
     31     M_SOF13 = 0xcd,
     32     M_SOF14 = 0xce,
     33     M_SOF15 = 0xcf,
     34 
     35     M_DHT   = 0xc4,
     36 
     37     M_DAC   = 0xcc,
     38 
     39     M_RST0  = 0xd0,
     40     M_RST1  = 0xd1,
     41     M_RST2  = 0xd2,
     42     M_RST3  = 0xd3,
     43     M_RST4  = 0xd4,
     44     M_RST5  = 0xd5,
     45     M_RST6  = 0xd6,
     46     M_RST7  = 0xd7,
     47 
     48     M_SOI   = 0xd8,
     49     M_EOI   = 0xd9,
     50     M_SOS   = 0xda,
     51     M_DQT   = 0xdb,
     52     M_DNL   = 0xdc,
     53     M_DRI   = 0xdd,
     54     M_DHP   = 0xde,
     55     M_EXP   = 0xdf,
     56 
     57     M_APP0  = 0xe0,
     58     M_APP1  = 0xe1,
     59     M_APP2  = 0xe2,
     60     M_APP3  = 0xe3,
     61     M_APP4  = 0xe4,
     62     M_APP5  = 0xe5,
     63     M_APP6  = 0xe6,
     64     M_APP7  = 0xe7,
     65     M_APP8  = 0xe8,
     66     M_APP9  = 0xe9,
     67     M_APP10 = 0xea,
     68     M_APP11 = 0xeb,
     69     M_APP12 = 0xec,
     70     M_APP13 = 0xed,
     71     M_APP14 = 0xee,
     72     M_APP15 = 0xef,
     73 
     74     M_JPG0  = 0xf0,
     75     M_JPG13 = 0xfd,
     76     M_COM   = 0xfe,
     77 
     78     M_TEM   = 0x01,
     79 
     80     M_ERROR = 0x100
     81 } JPEG_MARKER;
     82 
     83 
     84 /*
     85  * Basic output routines.
     86  *
     87  * Note that we do not support suspension while writing a marker.
     88  * Therefore, an application using suspension must ensure that there is
     89  * enough buffer space for the initial markers (typ. 600-700 bytes) before
     90  * calling jpeg_start_compress, and enough space to write the trailing EOI
     91  * (a few bytes) before calling jpeg_finish_compress.  Multipass compression
     92  * modes are not supported at all with suspension, so those two are the only
     93  * points where markers will be written.
     94  */
     95 
     96 LOCAL void
     97 emit_byte( j_compress_ptr cinfo, int val ) {
     98 /* Emit a byte */
     99     struct jpeg_destination_mgr * dest = cinfo->dest;
    100 
    101     *( dest->next_output_byte )++ = (JOCTET) val;
    102     if ( --dest->free_in_buffer == 0 ) {
    103         if ( !( *dest->empty_output_buffer )( cinfo ) ) {
    104             ERREXIT( cinfo, JERR_CANT_SUSPEND );
    105         }
    106     }
    107 }
    108 
    109 
    110 LOCAL void
    111 emit_marker( j_compress_ptr cinfo, JPEG_MARKER mark ) {
    112 /* Emit a marker code */
    113     emit_byte( cinfo, 0xFF );
    114     emit_byte( cinfo, (int) mark );
    115 }
    116 
    117 
    118 LOCAL void
    119 emit_2bytes( j_compress_ptr cinfo, int value ) {
    120 /* Emit a 2-byte integer; these are always MSB first in JPEG files */
    121     emit_byte( cinfo, ( value >> 8 ) & 0xFF );
    122     emit_byte( cinfo, value & 0xFF );
    123 }
    124 
    125 
    126 /*
    127  * Routines to write specific marker types.
    128  */
    129 
    130 LOCAL int
    131 emit_dqt( j_compress_ptr cinfo, int index ) {
    132 /* Emit a DQT marker */
    133 /* Returns the precision used (0 = 8bits, 1 = 16bits) for baseline checking */
    134     JQUANT_TBL * qtbl = cinfo->quant_tbl_ptrs[index];
    135     int prec;
    136     int i;
    137 
    138     if ( qtbl == NULL ) {
    139         ERREXIT1( cinfo, JERR_NO_QUANT_TABLE, index );
    140     }
    141 
    142     prec = 0;
    143     for ( i = 0; i < DCTSIZE2; i++ ) {
    144         if ( qtbl->quantval[i] > 255 ) {
    145             prec = 1;
    146         }
    147     }
    148 
    149     if ( !qtbl->sent_table ) {
    150         emit_marker( cinfo, M_DQT );
    151 
    152         emit_2bytes( cinfo, prec ? DCTSIZE2 * 2 + 1 + 2 : DCTSIZE2 + 1 + 2 );
    153 
    154         emit_byte( cinfo, index + ( prec << 4 ) );
    155 
    156         for ( i = 0; i < DCTSIZE2; i++ ) {
    157             if ( prec ) {
    158                 emit_byte( cinfo, qtbl->quantval[i] >> 8 );
    159             }
    160             emit_byte( cinfo, qtbl->quantval[i] & 0xFF );
    161         }
    162 
    163         qtbl->sent_table = TRUE;
    164     }
    165 
    166     return prec;
    167 }
    168 
    169 
    170 LOCAL void
    171 emit_dht( j_compress_ptr cinfo, int index, boolean is_ac ) {
    172 /* Emit a DHT marker */
    173     JHUFF_TBL * htbl;
    174     int length, i;
    175 
    176     if ( is_ac ) {
    177         htbl = cinfo->ac_huff_tbl_ptrs[index];
    178         index += 0x10;  /* output index has AC bit set */
    179     } else {
    180         htbl = cinfo->dc_huff_tbl_ptrs[index];
    181     }
    182 
    183     if ( htbl == NULL ) {
    184         ERREXIT1( cinfo, JERR_NO_HUFF_TABLE, index );
    185     }
    186 
    187     if ( !htbl->sent_table ) {
    188         emit_marker( cinfo, M_DHT );
    189 
    190         length = 0;
    191         for ( i = 1; i <= 16; i++ ) {
    192             length += htbl->bits[i];
    193         }
    194 
    195         emit_2bytes( cinfo, length + 2 + 1 + 16 );
    196         emit_byte( cinfo, index );
    197 
    198         for ( i = 1; i <= 16; i++ ) {
    199             emit_byte( cinfo, htbl->bits[i] );
    200         }
    201 
    202         for ( i = 0; i < length; i++ ) {
    203             emit_byte( cinfo, htbl->huffval[i] );
    204         }
    205 
    206         htbl->sent_table = TRUE;
    207     }
    208 }
    209 
    210 
    211 LOCAL void
    212 emit_dac( j_compress_ptr cinfo ) {
    213 /* Emit a DAC marker */
    214 /* Since the useful info is so small, we want to emit all the tables in */
    215 /* one DAC marker.  Therefore this routine does its own scan of the table. */
    216 #ifdef C_ARITH_CODING_SUPPORTED
    217     char dc_in_use[NUM_ARITH_TBLS];
    218     char ac_in_use[NUM_ARITH_TBLS];
    219     int length, i;
    220     jpeg_component_info * compptr;
    221 
    222     for ( i = 0; i < NUM_ARITH_TBLS; i++ ) {
    223         dc_in_use[i] = ac_in_use[i] = 0;
    224     }
    225 
    226     for ( i = 0; i < cinfo->comps_in_scan; i++ ) {
    227         compptr = cinfo->cur_comp_info[i];
    228         dc_in_use[compptr->dc_tbl_no] = 1;
    229         ac_in_use[compptr->ac_tbl_no] = 1;
    230     }
    231 
    232     length = 0;
    233     for ( i = 0; i < NUM_ARITH_TBLS; i++ ) {
    234         length += dc_in_use[i] + ac_in_use[i];
    235     }
    236 
    237     emit_marker( cinfo, M_DAC );
    238 
    239     emit_2bytes( cinfo, length * 2 + 2 );
    240 
    241     for ( i = 0; i < NUM_ARITH_TBLS; i++ ) {
    242         if ( dc_in_use[i] ) {
    243             emit_byte( cinfo, i );
    244             emit_byte( cinfo, cinfo->arith_dc_L[i] + ( cinfo->arith_dc_U[i] << 4 ) );
    245         }
    246         if ( ac_in_use[i] ) {
    247             emit_byte( cinfo, i + 0x10 );
    248             emit_byte( cinfo, cinfo->arith_ac_K[i] );
    249         }
    250     }
    251 #endif /* C_ARITH_CODING_SUPPORTED */
    252 }
    253 
    254 
    255 LOCAL void
    256 emit_dri( j_compress_ptr cinfo ) {
    257 /* Emit a DRI marker */
    258     emit_marker( cinfo, M_DRI );
    259 
    260     emit_2bytes( cinfo, 4 );/* fixed length */
    261 
    262     emit_2bytes( cinfo, (int) cinfo->restart_interval );
    263 }
    264 
    265 
    266 LOCAL void
    267 emit_sof( j_compress_ptr cinfo, JPEG_MARKER code ) {
    268 /* Emit a SOF marker */
    269     int ci;
    270     jpeg_component_info * compptr;
    271 
    272     emit_marker( cinfo, code );
    273 
    274     emit_2bytes( cinfo, 3 * cinfo->num_components + 2 + 5 + 1 );/* length */
    275 
    276     /* Make sure image isn't bigger than SOF field can handle */
    277     if ( ( (long) cinfo->image_height > 65535L ) ||
    278         ( (long) cinfo->image_width > 65535L ) ) {
    279         ERREXIT1( cinfo, JERR_IMAGE_TOO_BIG, (unsigned int) 65535 );
    280     }
    281 
    282     emit_byte( cinfo, cinfo->data_precision );
    283     emit_2bytes( cinfo, (int) cinfo->image_height );
    284     emit_2bytes( cinfo, (int) cinfo->image_width );
    285 
    286     emit_byte( cinfo, cinfo->num_components );
    287 
    288     for ( ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
    289           ci++, compptr++ ) {
    290         emit_byte( cinfo, compptr->component_id );
    291         emit_byte( cinfo, ( compptr->h_samp_factor << 4 ) + compptr->v_samp_factor );
    292         emit_byte( cinfo, compptr->quant_tbl_no );
    293     }
    294 }
    295 
    296 
    297 LOCAL void
    298 emit_sos( j_compress_ptr cinfo ) {
    299 /* Emit a SOS marker */
    300     int i, td, ta;
    301     jpeg_component_info * compptr;
    302 
    303     emit_marker( cinfo, M_SOS );
    304 
    305     emit_2bytes( cinfo, 2 * cinfo->comps_in_scan + 2 + 1 + 3 );/* length */
    306 
    307     emit_byte( cinfo, cinfo->comps_in_scan );
    308 
    309     for ( i = 0; i < cinfo->comps_in_scan; i++ ) {
    310         compptr = cinfo->cur_comp_info[i];
    311         emit_byte( cinfo, compptr->component_id );
    312         td = compptr->dc_tbl_no;
    313         ta = compptr->ac_tbl_no;
    314         if ( cinfo->progressive_mode ) {
    315             /* Progressive mode: only DC or only AC tables are used in one scan;
    316              * furthermore, Huffman coding of DC refinement uses no table at all.
    317              * We emit 0 for unused field(s); this is recommended by the P&M text
    318              * but does not seem to be specified in the standard.
    319              */
    320             if ( cinfo->Ss == 0 ) {
    321                 ta = 0;/* DC scan */
    322                 if ( ( cinfo->Ah != 0 ) && ( !cinfo->arith_code ) ) {
    323                     td = 0;
    324                 }   /* no DC table either */
    325             } else {
    326                 td = 0;/* AC scan */
    327             }
    328         }
    329         emit_byte( cinfo, ( td << 4 ) + ta );
    330     }
    331 
    332     emit_byte( cinfo, cinfo->Ss );
    333     emit_byte( cinfo, cinfo->Se );
    334     emit_byte( cinfo, ( cinfo->Ah << 4 ) + cinfo->Al );
    335 }
    336 
    337 
    338 LOCAL void
    339 emit_jfif_app0( j_compress_ptr cinfo ) {
    340 /* Emit a JFIF-compliant APP0 marker */
    341 /*
    342  * Length of APP0 block	(2 bytes)
    343  * Block ID			(4 bytes - ASCII "JFIF")
    344  * Zero byte			(1 byte to terminate the ID string)
    345  * Version Major, Minor	(2 bytes - 0x01, 0x01)
    346  * Units			(1 byte - 0x00 = none, 0x01 = inch, 0x02 = cm)
    347  * Xdpu			(2 bytes - dots per unit horizontal)
    348  * Ydpu			(2 bytes - dots per unit vertical)
    349  * Thumbnail X size		(1 byte)
    350  * Thumbnail Y size		(1 byte)
    351  */
    352 
    353     emit_marker( cinfo, M_APP0 );
    354 
    355     emit_2bytes( cinfo, 2 + 4 + 1 + 2 + 1 + 2 + 2 + 1 + 1 );/* length */
    356 
    357     emit_byte( cinfo, 0x4A );/* Identifier: ASCII "JFIF" */
    358     emit_byte( cinfo, 0x46 );
    359     emit_byte( cinfo, 0x49 );
    360     emit_byte( cinfo, 0x46 );
    361     emit_byte( cinfo, 0 );
    362     /* We currently emit version code 1.01 since we use no 1.02 features.
    363      * This may avoid complaints from some older decoders.
    364      */
    365     emit_byte( cinfo, 1 );  /* Major version */
    366     emit_byte( cinfo, 1 );  /* Minor version */
    367     emit_byte( cinfo, cinfo->density_unit );/* Pixel size information */
    368     emit_2bytes( cinfo, (int) cinfo->X_density );
    369     emit_2bytes( cinfo, (int) cinfo->Y_density );
    370     emit_byte( cinfo, 0 );  /* No thumbnail image */
    371     emit_byte( cinfo, 0 );
    372 }
    373 
    374 
    375 LOCAL void
    376 emit_adobe_app14( j_compress_ptr cinfo ) {
    377 /* Emit an Adobe APP14 marker */
    378 /*
    379  * Length of APP14 block	(2 bytes)
    380  * Block ID			(5 bytes - ASCII "Adobe")
    381  * Version Number		(2 bytes - currently 100)
    382  * Flags0			(2 bytes - currently 0)
    383  * Flags1			(2 bytes - currently 0)
    384  * Color transform		(1 byte)
    385  *
    386  * Although Adobe TN 5116 mentions Version = 101, all the Adobe files
    387  * now in circulation seem to use Version = 100, so that's what we write.
    388  *
    389  * We write the color transform byte as 1 if the JPEG color space is
    390  * YCbCr, 2 if it's YCCK, 0 otherwise.  Adobe's definition has to do with
    391  * whether the encoder performed a transformation, which is pretty useless.
    392  */
    393 
    394     emit_marker( cinfo, M_APP14 );
    395 
    396     emit_2bytes( cinfo, 2 + 5 + 2 + 2 + 2 + 1 );/* length */
    397 
    398     emit_byte( cinfo, 0x41 );/* Identifier: ASCII "Adobe" */
    399     emit_byte( cinfo, 0x64 );
    400     emit_byte( cinfo, 0x6F );
    401     emit_byte( cinfo, 0x62 );
    402     emit_byte( cinfo, 0x65 );
    403     emit_2bytes( cinfo, 100 );/* Version */
    404     emit_2bytes( cinfo, 0 );/* Flags0 */
    405     emit_2bytes( cinfo, 0 );/* Flags1 */
    406     switch ( cinfo->jpeg_color_space ) {
    407         case JCS_YCbCr:
    408             emit_byte( cinfo, 1 );/* Color transform = 1 */
    409             break;
    410         case JCS_YCCK:
    411             emit_byte( cinfo, 2 );/* Color transform = 2 */
    412             break;
    413         default:
    414             emit_byte( cinfo, 0 );/* Color transform = 0 */
    415             break;
    416     }
    417 }
    418 
    419 
    420 /*
    421  * This routine is exported for possible use by applications.
    422  * The intended use is to emit COM or APPn markers after calling
    423  * jpeg_start_compress() and before the first jpeg_write_scanlines() call
    424  * (hence, after write_file_header but before write_frame_header).
    425  * Other uses are not guaranteed to produce desirable results.
    426  */
    427 
    428 METHODDEF void
    429 write_any_marker( j_compress_ptr cinfo, int marker,
    430                   const JOCTET * dataptr, unsigned int datalen ) {
    431 /* Emit an arbitrary marker with parameters */
    432     if ( datalen <= (unsigned int) 65533 ) {/* safety check */
    433         emit_marker( cinfo, (JPEG_MARKER) marker );
    434 
    435         emit_2bytes( cinfo, (int) ( datalen + 2 ) );/* total length */
    436 
    437         while ( datalen-- ) {
    438             emit_byte( cinfo, *dataptr );
    439             dataptr++;
    440         }
    441     }
    442 }
    443 
    444 
    445 /*
    446  * Write datastream header.
    447  * This consists of an SOI and optional APPn markers.
    448  * We recommend use of the JFIF marker, but not the Adobe marker,
    449  * when using YCbCr or grayscale data.  The JFIF marker should NOT
    450  * be used for any other JPEG colorspace.  The Adobe marker is helpful
    451  * to distinguish RGB, CMYK, and YCCK colorspaces.
    452  * Note that an application can write additional header markers after
    453  * jpeg_start_compress returns.
    454  */
    455 
    456 METHODDEF void
    457 write_file_header( j_compress_ptr cinfo ) {
    458     emit_marker( cinfo, M_SOI );/* first the SOI */
    459 
    460     if ( cinfo->write_JFIF_header ) {/* next an optional JFIF APP0 */
    461         emit_jfif_app0( cinfo );
    462     }
    463     if ( cinfo->write_Adobe_marker ) {/* next an optional Adobe APP14 */
    464         emit_adobe_app14( cinfo );
    465     }
    466 }
    467 
    468 
    469 /*
    470  * Write frame header.
    471  * This consists of DQT and SOFn markers.
    472  * Note that we do not emit the SOF until we have emitted the DQT(s).
    473  * This avoids compatibility problems with incorrect implementations that
    474  * try to error-check the quant table numbers as soon as they see the SOF.
    475  */
    476 
    477 METHODDEF void
    478 write_frame_header( j_compress_ptr cinfo ) {
    479     int ci, prec;
    480     boolean is_baseline;
    481     jpeg_component_info * compptr;
    482 
    483     /* Emit DQT for each quantization table.
    484      * Note that emit_dqt() suppresses any duplicate tables.
    485      */
    486     prec = 0;
    487     for ( ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
    488           ci++, compptr++ ) {
    489         prec += emit_dqt( cinfo, compptr->quant_tbl_no );
    490     }
    491     /* now prec is nonzero iff there are any 16-bit quant tables. */
    492 
    493     /* Check for a non-baseline specification.
    494      * Note we assume that Huffman table numbers won't be changed later.
    495      */
    496     if ( ( cinfo->arith_code ) || ( cinfo->progressive_mode ) ||
    497         ( cinfo->data_precision != 8 ) ) {
    498         is_baseline = FALSE;
    499     } else {
    500         is_baseline = TRUE;
    501         for ( ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
    502               ci++, compptr++ ) {
    503             if ( ( compptr->dc_tbl_no > 1 ) || ( compptr->ac_tbl_no > 1 ) ) {
    504                 is_baseline = FALSE;
    505             }
    506         }
    507         if ( ( prec ) && ( is_baseline ) ) {
    508             is_baseline = FALSE;
    509             /* If it's baseline except for quantizer size, warn the user */
    510             TRACEMS( cinfo, 0, JTRC_16BIT_TABLES );
    511         }
    512     }
    513 
    514     /* Emit the proper SOF marker */
    515     if ( cinfo->arith_code ) {
    516         emit_sof( cinfo, M_SOF9 );/* SOF code for arithmetic coding */
    517     } else {
    518         if ( cinfo->progressive_mode ) {
    519             emit_sof( cinfo, M_SOF2 );
    520         }                       /* SOF code for progressive Huffman */
    521         else if ( is_baseline ) {
    522             emit_sof( cinfo, M_SOF0 );
    523         }                       /* SOF code for baseline implementation */
    524         else {
    525             emit_sof( cinfo, M_SOF1 );
    526         }                       /* SOF code for non-baseline Huffman file */
    527     }
    528 }
    529 
    530 
    531 /*
    532  * Write scan header.
    533  * This consists of DHT or DAC markers, optional DRI, and SOS.
    534  * Compressed data will be written following the SOS.
    535  */
    536 
    537 METHODDEF void
    538 write_scan_header( j_compress_ptr cinfo ) {
    539     int i;
    540     jpeg_component_info * compptr;
    541 
    542     if ( cinfo->arith_code ) {
    543         /* Emit arith conditioning info.  We may have some duplication
    544          * if the file has multiple scans, but it's so small it's hardly
    545          * worth worrying about.
    546          */
    547         emit_dac( cinfo );
    548     } else {
    549         /* Emit Huffman tables.
    550          * Note that emit_dht() suppresses any duplicate tables.
    551          */
    552         for ( i = 0; i < cinfo->comps_in_scan; i++ ) {
    553             compptr = cinfo->cur_comp_info[i];
    554             if ( cinfo->progressive_mode ) {
    555                 /* Progressive mode: only DC or only AC tables are used in one scan */
    556                 if ( cinfo->Ss == 0 ) {
    557                     if ( cinfo->Ah == 0 ) {/* DC needs no table for refinement scan */
    558                         emit_dht( cinfo, compptr->dc_tbl_no, FALSE );
    559                     }
    560                 } else {
    561                     emit_dht( cinfo, compptr->ac_tbl_no, TRUE );
    562                 }
    563             } else {
    564                 /* Sequential mode: need both DC and AC tables */
    565                 emit_dht( cinfo, compptr->dc_tbl_no, FALSE );
    566                 emit_dht( cinfo, compptr->ac_tbl_no, TRUE );
    567             }
    568         }
    569     }
    570 
    571     /* Emit DRI if required --- note that DRI value could change for each scan.
    572      * If it doesn't, a tiny amount of space is wasted in multiple-scan files.
    573      * We assume DRI will never be nonzero for one scan and zero for a later one.
    574      */
    575     if ( cinfo->restart_interval ) {
    576         emit_dri( cinfo );
    577     }
    578 
    579     emit_sos( cinfo );
    580 }
    581 
    582 
    583 /*
    584  * Write datastream trailer.
    585  */
    586 
    587 METHODDEF void
    588 write_file_trailer( j_compress_ptr cinfo ) {
    589     emit_marker( cinfo, M_EOI );
    590 }
    591 
    592 
    593 /*
    594  * Write an abbreviated table-specification datastream.
    595  * This consists of SOI, DQT and DHT tables, and EOI.
    596  * Any table that is defined and not marked sent_table = TRUE will be
    597  * emitted.  Note that all tables will be marked sent_table = TRUE at exit.
    598  */
    599 
    600 METHODDEF void
    601 write_tables_only( j_compress_ptr cinfo ) {
    602     int i;
    603 
    604     emit_marker( cinfo, M_SOI );
    605 
    606     for ( i = 0; i < NUM_QUANT_TBLS; i++ ) {
    607         if ( cinfo->quant_tbl_ptrs[i] != NULL ) {
    608             (void) emit_dqt( cinfo, i );
    609         }
    610     }
    611 
    612     if ( !cinfo->arith_code ) {
    613         for ( i = 0; i < NUM_HUFF_TBLS; i++ ) {
    614             if ( cinfo->dc_huff_tbl_ptrs[i] != NULL ) {
    615                 emit_dht( cinfo, i, FALSE );
    616             }
    617             if ( cinfo->ac_huff_tbl_ptrs[i] != NULL ) {
    618                 emit_dht( cinfo, i, TRUE );
    619             }
    620         }
    621     }
    622 
    623     emit_marker( cinfo, M_EOI );
    624 }
    625 
    626 
    627 /*
    628  * Initialize the marker writer module.
    629  */
    630 
    631 GLOBAL void
    632 jinit_marker_writer( j_compress_ptr cinfo ) {
    633     /* Create the subobject */
    634     cinfo->marker = (struct jpeg_marker_writer *)
    635                     ( * cinfo->mem->alloc_small )( (j_common_ptr) cinfo, JPOOL_IMAGE,
    636                                                   SIZEOF( struct jpeg_marker_writer ) );
    637     /* Initialize method pointers */
    638     cinfo->marker->write_any_marker = write_any_marker;
    639     cinfo->marker->write_file_header = write_file_header;
    640     cinfo->marker->write_frame_header = write_frame_header;
    641     cinfo->marker->write_scan_header = write_scan_header;
    642     cinfo->marker->write_file_trailer = write_file_trailer;
    643     cinfo->marker->write_tables_only = write_tables_only;
    644 }