home *** CD-ROM | disk | FTP | other *** search
/ PC World 2002 February / PCWorld_2002-02_cd.bin / Software / Vyzkuste / pdflib / pdflib-4.0.1.sit / pdflib-4.0.1 / pdflib / p_jpeg.c < prev    next >
Encoding:
C/C++ Source or Header  |  2001-07-04  |  15.3 KB  |  527 lines  |  [TEXT/CWIE]

  1. /*---------------------------------------------------------------------------*
  2.  |              PDFlib - A library for generating PDF on the fly             |
  3.  +---------------------------------------------------------------------------+
  4.  | Copyright (c) 1997-2001 PDFlib GmbH and Thomas Merz. All rights reserved. |
  5.  +---------------------------------------------------------------------------+
  6.  |    This software is NOT in the public domain.  It can be used under two   |
  7.  |    substantially different licensing terms:                               |
  8.  |                                                                           |
  9.  |    The commercial license is available for a fee, and allows you to       |
  10.  |    - ship a commercial product based on PDFlib                            |
  11.  |    - implement commercial Web services with PDFlib                        |
  12.  |    - distribute (free or commercial) software when the source code is     |
  13.  |      not made available                                                   |
  14.  |    Details can be found in the file PDFlib-license.pdf.                   |
  15.  |                                                                           |
  16.  |    The "Aladdin Free Public License" doesn't require any license fee,     |
  17.  |    and allows you to                                                      |
  18.  |    - develop and distribute PDFlib-based software for which the complete  |
  19.  |      source code is made available                                        |
  20.  |    - redistribute PDFlib non-commercially under certain conditions        |
  21.  |    - redistribute PDFlib on digital media for a fee if the complete       |
  22.  |      contents of the media are freely redistributable                     |
  23.  |    Details can be found in the file aladdin-license.pdf.                  |
  24.  |                                                                           |
  25.  |    These conditions extend to ports to other programming languages.       |
  26.  |    PDFlib is distributed with no warranty of any kind. Commercial users,  |
  27.  |    however, will receive warranty and support statements in writing.      |
  28.  *---------------------------------------------------------------------------*/
  29.  
  30. /* $Id: p_jpeg.c,v 1.10 2001/04/20 08:54:13 tm Exp $
  31.  *
  32.  * JPEG processing for PDFlib
  33.  *
  34.  */
  35.  
  36. #include <stdio.h>
  37. #include <string.h>
  38.  
  39. #include "p_intern.h"
  40. #include "p_image.h"
  41.  
  42. #ifndef PDF_JPEG_SUPPORTED
  43.  
  44. int
  45. pdf_open_JPEG_data(
  46.     PDF *p,
  47.     int imageslot,
  48.     const char *filename,
  49.     const char *stringparam,
  50.     int intparam)
  51. {
  52.     pdf_error(p, PDF_NonfatalError,
  53.     "JPEG images not supported in this configuration");
  54.  
  55.     return -1;
  56. }
  57.  
  58. #else
  59.  
  60.  
  61. /* 
  62.  * The following enum is stolen from the IJG JPEG library
  63.  * Comments added by tm.
  64.  * This table contains far too many names since PDFlib
  65.  * is rather simple-minded about markers.
  66.  */
  67.  
  68. typedef enum {        /* JPEG marker codes            */
  69.   M_SOF0  = 0xc0,    /* baseline DCT                */
  70.   M_SOF1  = 0xc1,    /* extended sequential DCT        */
  71.   M_SOF2  = 0xc2,    /* progressive DCT            */
  72.   M_SOF3  = 0xc3,    /* lossless (sequential)        */
  73.   
  74.   M_SOF5  = 0xc5,    /* differential sequential DCT        */
  75.   M_SOF6  = 0xc6,    /* differential progressive DCT        */
  76.   M_SOF7  = 0xc7,    /* differential lossless        */
  77.   
  78.   M_JPG   = 0xc8,    /* JPEG extensions            */
  79.   M_SOF9  = 0xc9,    /* extended sequential DCT        */
  80.   M_SOF10 = 0xca,    /* progressive DCT            */
  81.   M_SOF11 = 0xcb,    /* lossless (sequential)        */
  82.   
  83.   M_SOF13 = 0xcd,    /* differential sequential DCT        */
  84.   M_SOF14 = 0xce,    /* differential progressive DCT        */
  85.   M_SOF15 = 0xcf,    /* differential lossless        */
  86.   
  87.   M_DHT   = 0xc4,    /* define Huffman tables        */
  88.   
  89.   M_DAC   = 0xcc,    /* define arithmetic conditioning table    */
  90.   
  91.   M_RST0  = 0xd0,    /* restart                */
  92.   M_RST1  = 0xd1,    /* restart                */
  93.   M_RST2  = 0xd2,    /* restart                */
  94.   M_RST3  = 0xd3,    /* restart                */
  95.   M_RST4  = 0xd4,    /* restart                */
  96.   M_RST5  = 0xd5,    /* restart                */
  97.   M_RST6  = 0xd6,    /* restart                */
  98.   M_RST7  = 0xd7,    /* restart                */
  99.   
  100.   M_SOI   = 0xd8,    /* start of image            */
  101.   M_EOI   = 0xd9,    /* end of image                */
  102.   M_SOS   = 0xda,    /* start of scan            */
  103.   M_DQT   = 0xdb,    /* define quantization tables        */
  104.   M_DNL   = 0xdc,    /* define number of lines        */
  105.   M_DRI   = 0xdd,    /* define restart interval        */
  106.   M_DHP   = 0xde,    /* define hierarchical progression    */
  107.   M_EXP   = 0xdf,    /* expand reference image(s)        */
  108.   
  109.   M_APP0  = 0xe0,    /* application marker, used for JFIF    */
  110.   M_APP1  = 0xe1,    /* application marker            */
  111.   M_APP2  = 0xe2,    /* application marker            */
  112.   M_APP3  = 0xe3,    /* application marker            */
  113.   M_APP4  = 0xe4,    /* application marker            */
  114.   M_APP5  = 0xe5,    /* application marker            */
  115.   M_APP6  = 0xe6,    /* application marker            */
  116.   M_APP7  = 0xe7,    /* application marker            */
  117.   M_APP8  = 0xe8,    /* application marker            */
  118.   M_APP9  = 0xe9,    /* application marker            */
  119.   M_APP10 = 0xea,    /* application marker            */
  120.   M_APP11 = 0xeb,    /* application marker            */
  121.   M_APP12 = 0xec,    /* application marker            */
  122.   M_APP13 = 0xed,    /* application marker            */
  123.   M_APP14 = 0xee,    /* application marker, used by Adobe    */
  124.   M_APP15 = 0xef,    /* application marker            */
  125.   
  126.   M_JPG0  = 0xf0,    /* reserved for JPEG extensions        */
  127.   M_JPG13 = 0xfd,    /* reserved for JPEG extensions        */
  128.   M_COM   = 0xfe,    /* comment                */
  129.   
  130.   M_TEM   = 0x01,    /* temporary use            */
  131.  
  132.   M_ERROR = 0x100    /* dummy marker, internal use only    */
  133. } JPEG_MARKER;
  134.  
  135. #define JPEG_BUFSIZE    1024
  136.  
  137. static void
  138. pdf_data_source_JPEG_init(PDF *p, PDF_data_source *src)
  139. {
  140.   pdf_image    *image;
  141.  
  142.   image = (pdf_image *) src->private_data;
  143.  
  144.   src->buffer_start = (pdf_byte *)
  145.       p->malloc(p, JPEG_BUFSIZE, "PDF_data_source_JPEG_init");
  146.   src->buffer_length = JPEG_BUFSIZE;
  147.  
  148.   fseek(image->fp, image->info.jpeg.startpos, SEEK_SET);
  149. }
  150.  
  151. static pdf_bool
  152. pdf_data_source_JPEG_fill(PDF *p, PDF_data_source *src)
  153. {
  154.   pdf_image    *image;
  155.  
  156.   (void) p;    /* avoid compiler warning "unreferenced parameter" */
  157.  
  158.   image = (pdf_image *) src->private_data;
  159.  
  160.   src->next_byte = src->buffer_start;
  161.   src->bytes_available = fread(src->buffer_start, 1, JPEG_BUFSIZE, image->fp);
  162.  
  163.   if (src->bytes_available == 0)
  164.     return pdf_false;
  165.   else
  166.     return pdf_true;
  167. }
  168.  
  169. static void
  170. pdf_data_source_JPEG_terminate(PDF *p, PDF_data_source *src)
  171. {
  172.   p->free(p, (void *) src->buffer_start);
  173. }
  174.  
  175. /*
  176.  * The following routine used to be a macro in its first incarnation:
  177.  *
  178.  * #define get_2bytes(fp) ((unsigned int) (getc(fp) << 8) + getc(fp))
  179.  *
  180.  * However, this is bad programming since C doesn't guarantee
  181.  * the evaluation order of the getc() calls! As suggested by
  182.  * Murphy's law, there are indeed compilers which produce the wrong
  183.  * order of the getc() calls, e.g. the Metrowerks C compiler for BeOS.
  184.  * Since there are only a few calls we don't care about the performance 
  185.  * penalty and use a simplistic C function which does the right thing.
  186.  */
  187.  
  188. /* read two byte parameter, MSB first */
  189. static unsigned int
  190. get_2bytes(FILE *fp)
  191. {
  192.     unsigned int val;
  193.     val = (unsigned int) (getc(fp) << 8);
  194.     val += (unsigned int) getc(fp);
  195.     return val;
  196. }
  197.  
  198. static int 
  199. pdf_next_jpeg_marker(FILE *fp)
  200. { /* look for next JPEG Marker  */
  201.   int c;
  202.  
  203.   do {
  204.     do {                            /* skip to FF           */
  205.       if (feof(fp))
  206.     return M_ERROR;             /* dummy marker               */
  207.       c = getc(fp);
  208.     } while (c != 0xFF);
  209.  
  210.     do {                            /* skip repeated FFs        */
  211.       if (feof(fp))
  212.     return M_ERROR;             /* dummy marker               */
  213.       c = getc(fp);
  214.     } while (c == 0xFF);
  215.   } while (c == 0);                 /* repeat if FF/00                 */
  216.  
  217.   return c;
  218. }
  219.  
  220. /* open JPEG image and analyze marker */
  221. int
  222. pdf_open_JPEG_data(
  223.     PDF *p,
  224.     int imageslot,
  225.     const char *filename,
  226.     const char *stringparam,
  227.     int intparam)
  228. {
  229.     int b, c, unit;
  230.     unsigned long i, length;
  231. #define APP_MAX 255
  232.     unsigned char appstring[APP_MAX];
  233.     int SOF_done = pdf_false;
  234.     pdf_image *image;
  235.     int mask = -1;
  236.     pdf_bool adobeflag = pdf_false;
  237.  
  238.     image = &p->images[imageslot];
  239.  
  240.     if (stringparam && *stringparam) {
  241.     if (!strcmp(stringparam, "mask")) {
  242.         pdf_error(p, PDF_ValueError, "Can't handle JPEG image mask");
  243.  
  244.     } else if (!strcmp(stringparam, "masked")) {
  245.         mask = intparam;
  246.         if (mask >= 0 &&
  247.         (mask >= p->images_capacity || !p->images[mask].in_use ||
  248.         p->images[mask].colorspace != ImageMask)) {
  249.             pdf_error(p, PDF_ValueError,
  250.             "Bad image mask (no %d) for image '%s'", mask, filename);
  251.         }
  252.     }
  253.     else
  254.         pdf_error(p, PDF_ValueError,
  255.             "Unknown parameter %s in pdf_open_JPEG", stringparam);
  256.     }
  257.  
  258.     if ((image->fp = fopen(filename, READMODE)) == NULL) {
  259.     if (p->debug['i'])
  260.         pdf_error(p, PDF_NonfatalError,
  261.         "Couldn't open JPEG file '%s'", filename);
  262.     return -1;        /* Couldn't open JPEG file */
  263.     }
  264.  
  265.     image->mask            = mask;
  266.     image->compression        = dct;
  267.     image->use_raw        = pdf_true;
  268.  
  269.     image->src.init        = pdf_data_source_JPEG_init;
  270.     image->src.fill        = pdf_data_source_JPEG_fill;
  271.     image->src.terminate    = pdf_data_source_JPEG_terminate;
  272.     image->src.private_data    = (void *) image;
  273.  
  274.   /* Tommy's special trick for Macintosh JPEGs: simply skip some  */
  275.   /* hundred bytes at the beginning of the file!          */
  276.   do {
  277.     do {                            /* skip if not FF           */
  278.       c = getc(image->fp);
  279.     } while (!feof(image->fp) && c != 0xFF);
  280.  
  281.     if (feof(image->fp)) {
  282.     fclose(image->fp);
  283.     if (p->debug['i'])
  284.         pdf_error(p, PDF_NonfatalError,
  285.         "File problem with JPEG file '%s'", filename);
  286.     return -1;
  287.     }
  288.  
  289.     do {                            /* skip repeated FFs       */
  290.       c = getc(image->fp);
  291.     } while (c == 0xFF);
  292.  
  293.     /* remember start position */
  294.     if ((image->info.jpeg.startpos = ftell(image->fp)) < 0L) {
  295.     fclose(image->fp);
  296.     if (p->debug['i'])
  297.         pdf_error(p, PDF_NonfatalError,
  298.         "File problem with JPEG file '%s'", filename);
  299.     return -1;
  300.     }
  301.  
  302.     image->info.jpeg.startpos -= 2;    /* subtract marker length     */
  303.  
  304.     if (c == M_SOI) {
  305.       fseek(image->fp, image->info.jpeg.startpos, SEEK_SET);
  306.       break;
  307.     }
  308.   } while (!feof(image->fp));
  309.  
  310. #define BOGUS_LENGTH    768
  311.   /* Heuristics: if we are that far from the start chances are
  312.    * it is a TIFF file with embedded JPEG data which we cannot
  313.    * handle - regard as hopeless...
  314.    */
  315.   if (feof(image->fp) || image->info.jpeg.startpos > BOGUS_LENGTH) {
  316.     fclose(image->fp);
  317.     if (p->debug['i'])
  318.     pdf_error(p, PDF_NonfatalError,
  319.         "File '%s' doesn't appear to be of type JPEG", filename);
  320.     return -1;
  321.   }
  322.  
  323.   /* process JPEG markers */
  324.   while (!SOF_done && (c = pdf_next_jpeg_marker(image->fp)) != M_EOI) {
  325.     switch (c) {
  326.       case M_ERROR:
  327.       /* The following are not supported in PDF 1.3 */
  328.       case M_SOF3:
  329.       case M_SOF5:
  330.       case M_SOF6:
  331.       case M_SOF7:
  332.       case M_SOF9:
  333.       case M_SOF11:
  334.       case M_SOF13:
  335.       case M_SOF14:
  336.       case M_SOF15:
  337.     fclose(image->fp);
  338.         if (p->debug['i'])
  339.         pdf_error(p, PDF_NonfatalError,
  340.     "JPEG compression scheme '%d' in file '%s' is not supported in PDF 1.3",
  341.         (int) c, filename);
  342.     return -1;
  343.  
  344.       /*
  345.        * SOF2 and SOF10 are progressive DCT which are not
  346.        * supported prior to Acrobat 4.
  347.        */
  348.       case M_SOF2:
  349.       case M_SOF10:
  350.     if (p->compatibility == PDF_1_2) {
  351.         fclose(image->fp);
  352.         if (p->debug['i'])
  353.         pdf_error(p, PDF_NonfatalError, 
  354.             "Progressive JPEG images are not supported in PDF 1.2");
  355.         return -1;
  356.     }
  357.     /* fallthrough */
  358.  
  359.       case M_SOF0:
  360.       case M_SOF1:
  361.     (void) get_2bytes(image->fp);    /* read segment length  */
  362.  
  363.     image->bpc         = getc(image->fp);
  364.     image->height            = (float) get_2bytes(image->fp);
  365.     image->width             = (float) get_2bytes(image->fp);
  366.     image->components        = getc(image->fp);
  367.  
  368.     SOF_done = pdf_true;
  369.     break;
  370.  
  371.       case M_APP0:        /* check for JFIF marker with resolution */
  372.     length = get_2bytes(image->fp);
  373.  
  374.     for (i = 0; i < length-2; i++) {    /* get contents of marker */
  375.       b = getc(image->fp);
  376.       if (i < APP_MAX)            /* store marker in appstring */
  377.         appstring[i] = (unsigned char) b;
  378.     }
  379.  
  380.     /* Check for JFIF application marker and read density values
  381.      * per JFIF spec version 1.02.
  382.      */
  383.  
  384. #define ASPECT_RATIO    0    /* JFIF unit byte: aspect ratio only */
  385. #define DOTS_PER_INCH    1    /* JFIF unit byte: dots per inch     */
  386. #define DOTS_PER_CM    2    /* JFIF unit byte: dots per cm       */
  387.  
  388. #define PDF_STRING_JFIF    "\112\106\111\106"
  389.  
  390.     if (length >= 14 && !strncmp(PDF_STRING_JFIF, (char *) appstring, 4)) {
  391.       unit = appstring[7];                /* resolution unit */
  392.                           /* resolution value */
  393.       image->dpi_x = (float) ((appstring[8]<<8) + appstring[9]);    
  394.       image->dpi_y = (float) ((appstring[10]<<8) + appstring[11]);    
  395.  
  396.       if (image->dpi_x <= (float) 0.0 || image->dpi_y <= (float) 0.0) {
  397.         image->dpi_x = (float) 0.0;
  398.         image->dpi_y = (float) 0.0;
  399.         break;
  400.       }
  401.  
  402.       switch (unit) {
  403.         case DOTS_PER_INCH:
  404.           break;
  405.  
  406.         case DOTS_PER_CM:
  407.           image->dpi_x *= (float) 2.54;
  408.           image->dpi_y *= (float) 2.54;
  409.           break;
  410.  
  411.         case ASPECT_RATIO:
  412.           image->dpi_x *= -1;
  413.           image->dpi_y *= -1;
  414.           break;
  415.  
  416.         default:                /* unknown ==> ignore */
  417.         /* */ ;
  418.       }
  419.     }
  420.  
  421.         break;
  422.  
  423.       case M_APP14:                /* check for Adobe marker */
  424.     length = get_2bytes(image->fp);
  425.  
  426.     for (i = 0; i < length-2; i++) {    /* get contents of marker */
  427.       b = getc(image->fp);
  428.       if (i < APP_MAX)            /* store marker in appstring */
  429.         appstring[i] = (unsigned char) b;
  430.     }
  431.  
  432.     /* 
  433.      * Check for Adobe application marker. It is known (per Adobe's TN5116)
  434.      * to contain the string "Adobe" at the start of the APP14 marker.
  435.      */
  436. #define PDF_STRING_Adobe    "\101\144\157\142\145"
  437.  
  438.     if (length >= 12 && !strncmp(PDF_STRING_Adobe, (char *) appstring, 5))
  439.       adobeflag = pdf_true;        /* set Adobe flag */
  440.  
  441.     break;
  442.  
  443.       case M_SOI:        /* ignore markers without parameters */
  444.       case M_EOI:
  445.       case M_TEM:
  446.       case M_RST0:
  447.       case M_RST1:
  448.       case M_RST2:
  449.       case M_RST3:
  450.       case M_RST4:
  451.       case M_RST5:
  452.       case M_RST6:
  453.       case M_RST7:
  454.     break;
  455.  
  456.       default:            /* skip variable length markers */
  457.     length = get_2bytes(image->fp);
  458.     for (length -= 2; length > 0; length--) {
  459.       if (feof(image->fp)) {
  460.           fclose(image->fp);
  461.           if (p->debug['i'])
  462.           pdf_error(p, PDF_NonfatalError,
  463.               "JPEG file '%s' is damaged", filename);
  464.           return -1;
  465.       }
  466.       (void) getc(image->fp);
  467.     }
  468.     break;
  469.     }
  470.   }
  471.  
  472.   /* do some sanity checks with the parameters */
  473.   if (image->height <= 0 || image->width <= 0 || image->components <= 0) {
  474.     fclose(image->fp);
  475.     if (p->debug['i'])
  476.     pdf_error(p, PDF_NonfatalError,
  477.         "Bad image parameters in JPEG file '%s' (w=%d h=%d, colors=%d",
  478.         filename, image->width, image->height, image->components);
  479.     return -1;
  480.   }
  481.  
  482.   if (image->bpc != 8) {
  483.     fclose(image->fp);
  484.     if (p->debug['i'])
  485.     pdf_error(p, PDF_NonfatalError, 
  486.         "Bad number of bits per pixel (%d) in JPEG file '%s'",
  487.         image->bpc, filename);
  488.     return -1;
  489.   }
  490.  
  491.   switch (image->components) {
  492.     case 1:
  493.     image->colorspace = DeviceGray;
  494.     break;
  495.  
  496.     case 3:
  497.     image->colorspace = DeviceRGB;
  498.     break;
  499.  
  500.     case 4:
  501.     image->colorspace = DeviceCMYK;
  502.     /* special handling of Photoshop-generated CMYK JPEG files */
  503.     if (adobeflag)
  504.         image->invert = pdf_true;
  505.     break;
  506.  
  507.     default:
  508.     fclose(image->fp);
  509.     if (p->debug['i'])
  510.         pdf_error(p, PDF_NonfatalError,
  511.             "Unknown number of color components (%d) in JPEG file '%s'",
  512.         image->components, filename);
  513.     return -1;
  514.   }
  515.  
  516.     image->in_use    = pdf_true;        /* mark slot as used */
  517.  
  518.     image->filename    = pdf_strdup(p, filename);
  519.  
  520.     pdf_put_image(p, imageslot, pdf_true);
  521.     fclose(image->fp);
  522.  
  523.     return imageslot;
  524. }
  525.  
  526. #endif    /* PDF_JPEG_SUPPORTED */
  527.