Back to index

tetex-bin  3.0
writejpg.c
Go to the documentation of this file.
00001 /*
00002 Copyright (c) 1996-2002 Han The Thanh, <thanh@pdftex.org>
00003 
00004 This file is part of pdfTeX.
00005 
00006 pdfTeX is free software; you can redistribute it and/or modify
00007 it under the terms of the GNU General Public License as published by
00008 the Free Software Foundation; either version 2 of the License, or
00009 (at your option) any later version.
00010 
00011 pdfTeX is distributed in the hope that it will be useful,
00012 but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 GNU General Public License for more details.
00015 
00016 You should have received a copy of the GNU General Public License
00017 along with pdfTeX; if not, write to the Free Software
00018 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019 
00020 $Id: //depot/Build/source.development/TeX/texk/web2c/pdftexdir/writejpg.c#8 $
00021 */
00022 
00023 #include "ptexlib.h"
00024 #include "image.h"
00025 
00026 #define JPG_GRAY  1     /* Gray color space, use /DeviceGray  */
00027 #define JPG_RGB   3     /* RGB color space, use /DeviceRGB    */
00028 #define JPG_CMYK  4     /* CMYK color space, use /DeviceCMYK  */
00029 
00030 typedef enum {          /* JPEG marker codes                    */
00031   M_SOF0  = 0xc0,       /* baseline DCT                         */
00032   M_SOF1  = 0xc1,       /* extended sequential DCT              */
00033   M_SOF2  = 0xc2,       /* progressive DCT                      */
00034   M_SOF3  = 0xc3,       /* lossless (sequential)                */
00035 
00036   M_SOF5  = 0xc5,       /* differential sequential DCT          */
00037   M_SOF6  = 0xc6,       /* differential progressive DCT         */
00038   M_SOF7  = 0xc7,       /* differential lossless                */
00039 
00040   M_JPG   = 0xc8,       /* JPEG extensions                      */
00041   M_SOF9  = 0xc9,       /* extended sequential DCT              */
00042   M_SOF10 = 0xca,       /* progressive DCT                      */
00043   M_SOF11 = 0xcb,       /* lossless (sequential)                */
00044 
00045   M_SOF13 = 0xcd,       /* differential sequential DCT          */
00046   M_SOF14 = 0xce,       /* differential progressive DCT         */
00047   M_SOF15 = 0xcf,       /* differential lossless                */
00048 
00049   M_DHT   = 0xc4,       /* define Huffman tables                */
00050 
00051   M_DAC   = 0xcc,       /* define arithmetic conditioning table */
00052 
00053   M_RST0  = 0xd0,       /* restart                              */
00054   M_RST1  = 0xd1,       /* restart                              */
00055   M_RST2  = 0xd2,       /* restart                              */
00056   M_RST3  = 0xd3,       /* restart                              */
00057   M_RST4  = 0xd4,       /* restart                              */
00058   M_RST5  = 0xd5,       /* restart                              */
00059   M_RST6  = 0xd6,       /* restart                              */
00060   M_RST7  = 0xd7,       /* restart                              */
00061 
00062   M_SOI   = 0xd8,       /* start of image                       */
00063   M_EOI   = 0xd9,       /* end of image                         */
00064   M_SOS   = 0xda,       /* start of scan                        */
00065   M_DQT   = 0xdb,       /* define quantization tables           */
00066   M_DNL   = 0xdc,       /* define number of lines               */
00067   M_DRI   = 0xdd,       /* define restart interval              */
00068   M_DHP   = 0xde,       /* define hierarchical progression      */
00069   M_EXP   = 0xdf,       /* expand reference image(s)            */
00070 
00071   M_APP0  = 0xe0,       /* application marker, used for JFIF    */
00072   M_APP1  = 0xe1,       /* application marker                   */
00073   M_APP2  = 0xe2,       /* application marker                   */
00074   M_APP3  = 0xe3,       /* application marker                   */
00075   M_APP4  = 0xe4,       /* application marker                   */
00076   M_APP5  = 0xe5,       /* application marker                   */
00077   M_APP6  = 0xe6,       /* application marker                   */
00078   M_APP7  = 0xe7,       /* application marker                   */
00079   M_APP8  = 0xe8,       /* application marker                   */
00080   M_APP9  = 0xe9,       /* application marker                   */
00081   M_APP10 = 0xea,       /* application marker                   */
00082   M_APP11 = 0xeb,       /* application marker                   */
00083   M_APP12 = 0xec,       /* application marker                   */
00084   M_APP13 = 0xed,       /* application marker                   */
00085   M_APP14 = 0xee,       /* application marker, used by Adobe    */
00086   M_APP15 = 0xef,       /* application marker                   */
00087 
00088   M_JPG0  = 0xf0,       /* reserved for JPEG extensions         */
00089   M_JPG13 = 0xfd,       /* reserved for JPEG extensions         */
00090   M_COM   = 0xfe,       /* comment                              */
00091 
00092   M_TEM   = 0x01,       /* temporary use                        */
00093 
00094   M_ERROR = 0x100       /* dummy marker, internal use only      */
00095 } JPEG_MARKER;
00096 
00097 static JPG_UINT16 read2bytes(FILE *f)
00098 {
00099     int c = xgetc(f);
00100     return (c << 8) + xgetc(f);
00101 }
00102 
00103 void read_jpg_info(integer img)
00104 {
00105     int i;
00106     char jpg_id[]="JFIF";
00107     int units=0;
00108     img_xres(img)=img_yres(img)=0;
00109     jpg_ptr(img)->file = xfopen(img_name(img), FOPEN_RBIN_MODE);
00110     xfseek(jpg_ptr(img)->file,0,SEEK_END,cur_file_name);
00111     jpg_ptr(img)->length=xftell(jpg_ptr(img)->file,cur_file_name);
00112     xfseek(jpg_ptr(img)->file,0,SEEK_SET,cur_file_name);
00113     if(read2bytes(jpg_ptr(img)->file)!=0xFFD8)
00114         pdftex_fail("reading JPEG image failed");
00115 
00116     if(read2bytes(jpg_ptr(img)->file)==0xFFE0) { /* JFIF APP0 */
00117       (void)read2bytes(jpg_ptr(img)->file);
00118       for(i=0;i<5;i++) if(xgetc(jpg_ptr(img)->file)!=jpg_id[i])
00119         pdftex_fail("reading JPEG image failed");
00120       (void)read2bytes(jpg_ptr(img)->file);
00121       units=xgetc(jpg_ptr(img)->file);
00122       img_xres(img)=read2bytes(jpg_ptr(img)->file);
00123       img_yres(img)=read2bytes(jpg_ptr(img)->file);
00124       switch(units) {
00125           case 1: break; /* pixels per inch */
00126           case 2: img_xres(img)*=2.54; img_yres(img)*=2.54;
00127                   break; /* pixels per cm */
00128           default:img_xres(img)=img_yres(img)=0; break;
00129       }
00130     }
00131 
00132     xfseek(jpg_ptr(img)->file,0,SEEK_SET,cur_file_name);
00133     while(1) {
00134         if(feof(jpg_ptr(img)->file) || fgetc(jpg_ptr(img)->file)!=0xFF)
00135             pdftex_fail("reading JPEG image failed");
00136         switch(xgetc(jpg_ptr(img)->file)) {
00137         case M_SOF5:
00138         case M_SOF6:
00139         case M_SOF7:
00140         case M_SOF9:
00141         case M_SOF10:
00142         case M_SOF11:
00143         case M_SOF13:
00144         case M_SOF14:
00145         case M_SOF15:
00146             pdftex_fail("unsupported type of compression");
00147         case M_SOF2:
00148          if (getintpar(cfgpdfminorversioncode) <= 2)
00149                  pdftex_fail("cannot use progressive DCT with PDF-1.2");
00150         case M_SOF0:
00151         case M_SOF1:
00152         case M_SOF3:
00153              (void)read2bytes(jpg_ptr(img)->file);    /* read segment length  */
00154              jpg_ptr(img)->bits_per_component = xgetc(jpg_ptr(img)->file);
00155              img_height(img)       = read2bytes(jpg_ptr(img)->file);
00156              img_width(img)        = read2bytes(jpg_ptr(img)->file);
00157              jpg_ptr(img)->color_space  = xgetc(jpg_ptr(img)->file);
00158              xfseek(jpg_ptr(img)->file,0,SEEK_SET,cur_file_name); 
00159              switch (jpg_ptr(img)->color_space) {
00160                  case JPG_GRAY:
00161                      img_color(img) = IMAGE_COLOR_B;
00162                      break;
00163                  case JPG_RGB:
00164                      img_color(img) = IMAGE_COLOR_C;
00165                      break;
00166                  case JPG_CMYK:
00167                      img_color(img) = IMAGE_COLOR_C;
00168                      break;
00169                  default:
00170                      pdftex_fail("Unsupported color space %i", 
00171                              (int)jpg_ptr(img)->color_space);
00172              }
00173              return;
00174         case M_SOI:             /* ignore markers without parameters */
00175         case M_EOI:
00176         case M_TEM:
00177         case M_RST0:
00178         case M_RST1:
00179         case M_RST2:
00180         case M_RST3:
00181         case M_RST4:
00182         case M_RST5:
00183         case M_RST6:
00184         case M_RST7:
00185             break;
00186         default:                        /* skip variable length markers */
00187             xfseek(jpg_ptr(img)->file,read2bytes(jpg_ptr(img)->file)-2,SEEK_CUR,cur_file_name);
00188             break;
00189         }
00190     }
00191 }
00192 
00193 void write_jpg(integer img)
00194 {
00195     long unsigned l;
00196     FILE *f;
00197     pdf_puts("/Type /XObject\n/Subtype /Image\n");
00198     pdf_printf("/Width %i\n/Height %i\n/BitsPerComponent %i\n/Length %i\n",
00199                img_width(img),
00200                img_height(img),
00201                (int)jpg_ptr(img)->bits_per_component,
00202                (int)jpg_ptr(img)->length);
00203     pdf_puts("/ColorSpace ");
00204     if (img_colorspace_ref(img) != 0) {
00205         pdf_printf("%i 0 R\n", (int)img_colorspace_ref(img));
00206     }
00207     else {
00208         switch (jpg_ptr(img)->color_space) {
00209         case JPG_GRAY:
00210             pdf_puts("/DeviceGray\n");
00211             break;
00212         case JPG_RGB:
00213             pdf_puts("/DeviceRGB\n");
00214             break;
00215         case JPG_CMYK:
00216             pdf_puts("/DeviceCMYK\n/Decode [1 0 1 0 1 0 1 0]\n");
00217             break;
00218         default:
00219             pdftex_fail("Unsupported color space %i", 
00220                  (int)jpg_ptr(img)->color_space);
00221         }
00222     }
00223     pdf_puts("/Filter /DCTDecode\n>>\nstream\n");
00224     for (l = jpg_ptr(img)->length, f = jpg_ptr(img)->file; l > 0; l--)
00225         pdfout(xgetc(f));
00226     pdf_puts("endstream\nendobj\n");
00227 }