home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / general / procssng / ccs / ccs-11tl.lha / lbl / jpeg / lib / jwrjfif.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-03-16  |  12.8 KB  |  523 lines

  1. /*
  2.  * jwrjfif.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 write standard JPEG file headers/markers.
  9.  * The file format created is a raw JPEG data stream with (optionally) an
  10.  * APP0 marker per the JFIF spec.  This will handle baseline and
  11.  * JFIF-convention JPEG files, although there is currently no provision
  12.  * for inserting a thumbnail image in the JFIF header.
  13.  *
  14.  * These routines may need modification for non-Unix environments or
  15.  * specialized applications.  As they stand, they assume output to
  16.  * an ordinary stdio stream.  However, the changes to write to something
  17.  * else are localized in the macros appearing just below.
  18.  *
  19.  * These routines are invoked via the methods write_file_header,
  20.  * write_scan_header, write_jpeg_data, write_scan_trailer, and
  21.  * write_file_trailer.
  22. %
  23. % Modified:     Jin Guojun - LBL, Image Technology Group
  24. %       Date:   April 14, 1992
  25. %       Goal:   To be easily handled by conversion library - CCS (c)
  26. %        HIPS, FITS, GIF, RLE, SUN-raster, PNM, TIFF, PICT ...
  27. %        can be compressed by cjpeg now, directly displayed by tuner,
  28. %        decompressed to other image type by torle, torast, and color_ps.
  29. %        These type of images can be determined by program `headers'.
  30.  */
  31.  
  32. #include "jinclude.h"
  33.  
  34. #ifdef JFIF_SUPPORTED
  35.  
  36.  
  37. /*
  38.  * To output to something other than a stdio stream, you'd need to redefine
  39.  * these macros.
  40.  */
  41.  
  42. /* Write a single byte */
  43. #define emit_byte(cinfo,x)  putc((x), cinfo->output_file)
  44.  
  45. /* Write some bytes from a (char *) buffer */
  46. #define WRITE_BYTES(cinfo,dataptr,datacount)  \
  47.   { if (JFWRITE(cinfo->output_file, dataptr, datacount) \
  48.     != (size_t) (datacount)) \
  49.       ERREXIT(cinfo->emethods, "Output file write error"); }
  50.  
  51. /* Clean up and verify successful output */
  52. #define CHECK_OUTPUT(cinfo)  \
  53.   { fflush(cinfo->output_file); \
  54.     if (ferror(cinfo->output_file)) \
  55.       ERREXIT(cinfo->emethods, "Output file write error"); }
  56.  
  57.  
  58. /* End of stdio-specific code. */
  59.  
  60.  
  61. typedef enum {            /* JPEG marker codes */
  62.   M_SOF0  = 0xc0,
  63.   M_SOF1  = 0xc1,
  64.   M_SOF2  = 0xc2,
  65.   M_SOF3  = 0xc3,
  66.   
  67.   M_SOF5  = 0xc5,
  68.   M_SOF6  = 0xc6,
  69.   M_SOF7  = 0xc7,
  70.   
  71.   M_JPG   = 0xc8,
  72.   M_SOF9  = 0xc9,
  73.   M_SOF10 = 0xca,
  74.   M_SOF11 = 0xcb,
  75.   
  76.   M_SOF13 = 0xcd,
  77.   M_SOF14 = 0xce,
  78.   M_SOF15 = 0xcf,
  79.   
  80.   M_DHT   = 0xc4,
  81.   
  82.   M_DAC   = 0xcc,
  83.   
  84.   M_RST0  = 0xd0,
  85.   M_RST1  = 0xd1,
  86.   M_RST2  = 0xd2,
  87.   M_RST3  = 0xd3,
  88.   M_RST4  = 0xd4,
  89.   M_RST5  = 0xd5,
  90.   M_RST6  = 0xd6,
  91.   M_RST7  = 0xd7,
  92.   
  93.   M_SOI   = 0xd8,
  94.   M_EOI   = 0xd9,
  95.   M_SOS   = 0xda,
  96.   M_DQT   = 0xdb,
  97.   M_DNL   = 0xdc,
  98.   M_DRI   = 0xdd,
  99.   M_DHP   = 0xde,
  100.   M_EXP   = 0xdf,
  101.   
  102.   M_APP0  = 0xe0,
  103.   M_APP15 = 0xef,
  104.   
  105.   M_JPG0  = 0xf0,
  106.   M_JPG13 = 0xfd,
  107.   M_COM   = 0xfe,
  108.   
  109.   M_TEM   = 0x01,
  110.   
  111.   M_ERROR = 0x100
  112. } JPEG_MARKER;
  113.  
  114.  
  115. LOCAL void
  116. emit_marker (compress_info_ptr cinfo, JPEG_MARKER mark)
  117. /* Emit a marker code */
  118. {
  119.   emit_byte(cinfo, 0xFF);
  120.   emit_byte(cinfo, mark);
  121. }
  122.  
  123.  
  124. LOCAL void
  125. emit_2bytes (compress_info_ptr cinfo, int value)
  126. /* Emit a 2-byte integer; these are always MSB first in JPEG files */
  127. {
  128.   emit_byte(cinfo, (value >> 8) & 0xFF);
  129.   emit_byte(cinfo, value & 0xFF);
  130. }
  131.  
  132.  
  133. LOCAL int
  134. emit_dqt (compress_info_ptr cinfo, int index)
  135. /* Emit a DQT marker */
  136. /* Returns the precision used (0 = 8bits, 1 = 16bits) for baseline checking */
  137. {
  138.   QUANT_TBL_PTR data = cinfo->quant_tbl_ptrs[index];
  139.   int prec = 0;
  140.   int i;
  141.   
  142.   for (i = 0; i < DCTSIZE2; i++) {
  143.     if (data[i] > 255)
  144.       prec = 1;
  145.   }
  146.  
  147.   emit_marker(cinfo, M_DQT);
  148.   
  149.   emit_2bytes(cinfo, prec ? DCTSIZE2*2 + 1 + 2 : DCTSIZE2 + 1 + 2);
  150.   
  151.   emit_byte(cinfo, index + (prec<<4));
  152.   
  153.   for (i = 0; i < DCTSIZE2; i++) {
  154.     if (prec)
  155.       emit_byte(cinfo, data[i] >> 8);
  156.     emit_byte(cinfo, data[i] & 0xFF);
  157.   }
  158.  
  159.   return prec;
  160. }
  161.  
  162.  
  163. LOCAL void
  164. emit_dht (compress_info_ptr cinfo, int index, boolean is_ac)
  165. /* Emit a DHT marker */
  166. {
  167.   HUFF_TBL * htbl;
  168.   int length, i;
  169.   
  170.   if (is_ac) {
  171.     htbl = cinfo->ac_huff_tbl_ptrs[index];
  172.     index += 0x10;        /* output index has AC bit set */
  173.   } else {
  174.     htbl = cinfo->dc_huff_tbl_ptrs[index];
  175.   }
  176.  
  177.   if (htbl == NULL)
  178.     ERREXIT1(cinfo->emethods, "Huffman table 0x%02x was not defined", index);
  179.   
  180.   if (! htbl->sent_table) {
  181.     emit_marker(cinfo, M_DHT);
  182.     
  183.     length = 0;
  184.     for (i = 1; i <= 16; i++)
  185.       length += htbl->bits[i];
  186.     
  187.     emit_2bytes(cinfo, length + 2 + 1 + 16);
  188.     emit_byte(cinfo, index);
  189.     
  190.     for (i = 1; i <= 16; i++)
  191.       emit_byte(cinfo, htbl->bits[i]);
  192.     
  193.     for (i = 0; i < length; i++)
  194.       emit_byte(cinfo, htbl->huffval[i]);
  195.     
  196.     htbl->sent_table = TRUE;
  197.   }
  198. }
  199.  
  200.  
  201. LOCAL void
  202. emit_dac (compress_info_ptr cinfo)
  203. /* Emit a DAC marker */
  204. /* Since the useful info is so small, we want to emit all the tables in */
  205. /* one DAC marker.  Therefore this routine does its own scan of the table. */
  206. {
  207.   char dc_in_use[NUM_ARITH_TBLS];
  208.   char ac_in_use[NUM_ARITH_TBLS];
  209.   int length, i;
  210.   
  211.   for (i = 0; i < NUM_ARITH_TBLS; i++)
  212.     dc_in_use[i] = ac_in_use[i] = 0;
  213.   
  214.   for (i = 0; i < cinfo->num_components; i++) {
  215.     dc_in_use[cinfo->comp_info[i].dc_tbl_no] = 1;
  216.     ac_in_use[cinfo->comp_info[i].ac_tbl_no] = 1;
  217.   }
  218.   
  219.   length = 0;
  220.   for (i = 0; i < NUM_ARITH_TBLS; i++)
  221.     length += dc_in_use[i] + ac_in_use[i];
  222.   
  223.   emit_marker(cinfo, M_DAC);
  224.   
  225.   emit_2bytes(cinfo, length*2 + 2);
  226.   
  227.   for (i = 0; i < NUM_ARITH_TBLS; i++) {
  228.     if (dc_in_use[i]) {
  229.       emit_byte(cinfo, i);
  230.       emit_byte(cinfo, cinfo->arith_dc_L[i] + (cinfo->arith_dc_U[i]<<4));
  231.     }
  232.     if (ac_in_use[i]) {
  233.       emit_byte(cinfo, i + 0x10);
  234.       emit_byte(cinfo, cinfo->arith_ac_K[i]);
  235.     }
  236.   }
  237. }
  238.  
  239.  
  240. LOCAL void
  241. emit_dri (compress_info_ptr cinfo)
  242. /* Emit a DRI marker */
  243. {
  244.   emit_marker(cinfo, M_DRI);
  245.   
  246.   emit_2bytes(cinfo, 4);    /* fixed length */
  247.  
  248.   emit_2bytes(cinfo, (int) cinfo->restart_interval);
  249. }
  250.  
  251.  
  252. LOCAL void
  253. emit_sof (compress_info_ptr cinfo, JPEG_MARKER code)
  254. /* Emit a SOF marker */
  255. {
  256.   int i;
  257.   
  258.   emit_marker(cinfo, code);
  259.   
  260.   emit_2bytes(cinfo, 3 * cinfo->num_components + 2 + 5 + 1); /* length */
  261.  
  262.   if (cinfo->image_height > 65535L || cinfo->image_width > 65535L)
  263.     ERREXIT(cinfo->emethods, "Maximum image dimension for JFIF is 65535 pixels");
  264.  
  265.   emit_byte(cinfo, cinfo->data_precision);
  266.   emit_2bytes(cinfo, (int) cinfo->image_height);
  267.   emit_2bytes(cinfo, (int) cinfo->image_width);
  268.  
  269.   emit_byte(cinfo, cinfo->num_components);
  270.  
  271.   for (i = 0; i < cinfo->num_components; i++) {
  272.     emit_byte(cinfo, cinfo->comp_info[i].component_id);
  273.     emit_byte(cinfo, (cinfo->comp_info[i].h_samp_factor << 4)
  274.              + cinfo->comp_info[i].v_samp_factor);
  275.     emit_byte(cinfo, cinfo->comp_info[i].quant_tbl_no);
  276.   }
  277. }
  278.  
  279.  
  280. LOCAL void
  281. emit_sos (compress_info_ptr cinfo)
  282. /* Emit a SOS marker */
  283. {
  284.   int i;
  285.   
  286.   emit_marker(cinfo, M_SOS);
  287.   
  288.   emit_2bytes(cinfo, 2 * cinfo->comps_in_scan + 2 + 1 + 3); /* length */
  289.   
  290.   emit_byte(cinfo, cinfo->comps_in_scan);
  291.   
  292.   for (i = 0; i < cinfo->comps_in_scan; i++) {
  293.     emit_byte(cinfo, cinfo->cur_comp_info[i]->component_id);
  294.     emit_byte(cinfo, (cinfo->cur_comp_info[i]->dc_tbl_no << 4)
  295.              + cinfo->cur_comp_info[i]->ac_tbl_no);
  296.   }
  297.  
  298.   emit_byte(cinfo, 0);        /* Spectral selection start */
  299.   emit_byte(cinfo, DCTSIZE2-1);    /* Spectral selection end */
  300.   emit_byte(cinfo, 0);        /* Successive approximation */
  301.   cinfo->img->tmp_offset = 8 + (i<<1);
  302. #ifdef    _DEBUG_
  303.     fprintf(stderr, "SOS size = %d\n", cinfo->img->tmp_offset);
  304. #endif
  305. }
  306.  
  307.  
  308. LOCAL void
  309. emit_jfif_app0 (compress_info_ptr cinfo)
  310. /* Emit a JFIF-compliant APP0 marker */
  311. {
  312.   /*
  313.    * Length of APP0 block    (2 bytes)
  314.    * Block ID            (4 bytes - ASCII "JFIF")
  315.    * Zero byte            (1 byte to terminate the ID string)
  316.    * Version Major, Minor    (2 bytes - 0x01, 0x01)
  317.    * Units            (1 byte - 0x00 = none, 0x01 = inch, 0x02 = cm)
  318.    * Xdpu            (2 bytes - dots per unit horizontal)
  319.    * Ydpu            (2 bytes - dots per unit vertical)
  320.    * Thumbnail X size        (1 byte)
  321.    * Thumbnail Y size        (1 byte)
  322.    * FMarker + Frames        (4 bytes)
  323.    */
  324.   
  325.   emit_marker(cinfo, M_APP0);
  326.   
  327.   emit_2bytes(cinfo, 2 + 4 + 1 + 2 + 1 + 2 + 2 + 1 + 1 + 4); /* length */
  328.  
  329.   emit_byte(cinfo, 0x4A);    /* Identifier: ASCII "JFIF" */
  330.   emit_byte(cinfo, 0x46);
  331.   emit_byte(cinfo, 0x49);
  332.   emit_byte(cinfo, 0x46);
  333.   emit_byte(cinfo, 0);
  334.   emit_byte(cinfo, 1);        /* Major version */
  335.   emit_byte(cinfo, 1);        /* Minor version */
  336.   emit_byte(cinfo, cinfo->density_unit); /* Pixel size information */
  337.   emit_2bytes(cinfo, (int) cinfo->X_density);
  338.   emit_2bytes(cinfo, (int) cinfo->Y_density);
  339.   emit_byte(cinfo, 0);        /* No thumbnail image */
  340.   emit_byte(cinfo, 0);
  341.   emit_marker(cinfo, 0x7F);
  342.   emit_2bytes(cinfo, (int) cinfo->img->frames);
  343. }
  344.  
  345.  
  346. /*
  347.  * Write the file header.
  348.  */
  349.  
  350. #ifdef    STREAM_IMAGE
  351. static int    header_start;
  352. #endif
  353.  
  354. METHODDEF void
  355. write_file_header (compress_info_ptr cinfo)
  356. {
  357.   char qt_in_use[NUM_QUANT_TBLS];
  358.   int i, prec;
  359.   boolean is_baseline;
  360.   
  361.   emit_marker(cinfo, M_SOI);    /* first the SOI */
  362.  
  363.   if (cinfo->write_JFIF_header)    /* next an optional JFIF APP0 */
  364.     emit_jfif_app0(cinfo);
  365.  
  366.   /* Emit DQT for each quantization table. */
  367.   /* Note that doing it here means we can't adjust the QTs on-the-fly. */
  368.   /* If we did want to do that, we'd have a problem with checking precision */
  369.   /* for the is_baseline determination. */
  370.  
  371.   for (i = 0; i < NUM_QUANT_TBLS; i++)
  372.     qt_in_use[i] = 0;
  373.  
  374.   for (i = 0; i < cinfo->num_components; i++)
  375.     qt_in_use[cinfo->comp_info[i].quant_tbl_no] = 1;
  376.  
  377.   prec = 0;
  378.   for (i = 0; i < NUM_QUANT_TBLS; i++) {
  379.     if (qt_in_use[i])
  380.       prec += emit_dqt(cinfo, i);
  381.   }
  382.   /* now prec is nonzero iff there are any 16-bit quant tables. ??? */
  383.  
  384.   /* Check for a non-baseline specification. */
  385.   /* Note we assume that Huffman table numbers won't be changed later. */
  386.   is_baseline = TRUE;
  387.   if (cinfo->arith_code || (cinfo->data_precision != 8))
  388.     is_baseline = FALSE;
  389.   for (i = 0; i < cinfo->num_components; i++) {
  390.     if (cinfo->comp_info[i].dc_tbl_no > 1 || cinfo->comp_info[i].ac_tbl_no > 1)
  391.       is_baseline = FALSE;
  392.   }
  393.   if (prec && is_baseline) {
  394.     is_baseline = FALSE;
  395.     /* If it's baseline except for quantizer size, warn the user */
  396.     TRACEMS(cinfo->emethods, 0,
  397.         "Caution: quantization tables are too coarse for baseline JPEG");
  398.   }
  399.  
  400.  
  401.   /* Emit the proper SOF marker */
  402.   if (cinfo->arith_code)
  403.     emit_sof(cinfo, M_SOF9);    /* SOF code for arithmetic coding */
  404.   else if (is_baseline)
  405.     emit_sof(cinfo, M_SOF0);    /* SOF code for baseline implementation */
  406.   else
  407.     emit_sof(cinfo, M_SOF1);    /* SOF code for non-baseline Huffman file */
  408. #ifdef    STREAM_IMAGE
  409.   header_start = -1;
  410. #endif
  411. }
  412.  
  413.  
  414. /*
  415.  * Write the start of a scan (everything through the SOS marker).
  416.  */
  417.  
  418. METHODDEF void
  419. write_scan_header (compress_info_ptr cinfo)
  420. {
  421.   int i;
  422.  
  423. #ifdef     STREAM_IMAGE
  424.   if (!header_start++)    {
  425.     cinfo->img->tmp_offset = 0;
  426.     return;
  427.   }
  428. #endif
  429.  
  430.   if (cinfo->arith_code) {
  431.     /* Emit arith conditioning info.  We will have some duplication
  432.      * if the file has multiple scans, but it's so small it's hardly
  433.      * worth worrying about.
  434.      */
  435.     emit_dac(cinfo);
  436.   } else {
  437.     /* Emit Huffman tables.  Note that emit_dht takes care of
  438.      * suppressing duplicate tables.
  439.      */
  440.     for (i = 0; i < cinfo->comps_in_scan; i++) {
  441.       emit_dht(cinfo, cinfo->cur_comp_info[i]->dc_tbl_no, FALSE);
  442.       emit_dht(cinfo, cinfo->cur_comp_info[i]->ac_tbl_no, TRUE);
  443.     }
  444.   }
  445.  
  446.   /* Emit DRI if required --- note that DRI value could change for each scan.
  447.    * If it doesn't, a tiny amount of space is wasted in multiple-scan files.
  448.    * We assume DRI will never be nonzero for one scan and zero for a later one.
  449.    */
  450.   if (cinfo->restart_interval)
  451.     emit_dri(cinfo);
  452.  
  453.   emit_sos(cinfo);
  454. }
  455.  
  456.  
  457. /*
  458.  * Write some bytes of compressed data within a scan.
  459.  */
  460.  
  461. METHODDEF void
  462. write_jpeg_data (compress_info_ptr cinfo, char *dataptr, int datacount)
  463. {
  464. register U_IMAGE *img = cinfo->img;
  465.  
  466.     if (img->o_form != IFMT_STREAM)    {
  467.         WRITE_BYTES(cinfo, dataptr, datacount);
  468.     } else  {
  469.         memcpy(img->dest, dataptr, datacount);
  470.         img->dest = (char*)img->dest + datacount;
  471.     }
  472.     img->tmp_offset += datacount;
  473. }
  474.  
  475.  
  476. /*
  477.  * Finish up after a compressed scan (series of write_jpeg_data calls).
  478.  */
  479.  
  480. METHODDEF void
  481. write_scan_trailer (compress_info_ptr cinfo)
  482. {
  483.   /* no work needed in this format */
  484. }
  485.  
  486.  
  487. /*
  488.  * Finish up at the end of the file.
  489.  */
  490.  
  491. METHODDEF void
  492. write_file_trailer (compress_info_ptr cinfo)
  493. {
  494.   emit_marker(cinfo, M_EOI);
  495.   /* Make sure we wrote the output file OK */
  496.   CHECK_OUTPUT(cinfo);
  497. }
  498.  
  499.  
  500. /*
  501.  * The method selection routine for standard JPEG header writing.
  502.  * This should be called from c_ui_method_selection if appropriate.
  503.  */
  504.  
  505. GLOBAL void
  506. jselwjfif (compress_info_ptr cinfo)
  507. {
  508.   cinfo->methods->write_file_header = write_file_header;
  509.   cinfo->methods->write_scan_header = write_scan_header;
  510.   cinfo->methods->write_jpeg_data = write_jpeg_data;
  511.   cinfo->methods->write_scan_trailer = write_scan_trailer;
  512.   cinfo->methods->write_file_trailer = write_file_trailer;
  513. }
  514.  
  515. #ifdef    STREAM_IMAGE
  516. reset_stream_jpeg_header()
  517. {
  518.    header_start = -1;
  519. }
  520. #endif
  521.  
  522. #endif /* JFIF_SUPPORTED */
  523.