Back to index

tetex-bin  3.0
writeimg.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/writeimg.c#15 $
00021 */
00022 
00023 #include "ptexlib.h"
00024 #include "image.h"
00025 #include <kpathsea/c-auto.h>
00026 #include <kpathsea/c-memstr.h>
00027 
00028 static const char perforce_id[] = 
00029     "$Id: //depot/Build/source.development/TeX/texk/web2c/pdftexdir/writeimg.c#15 $";
00030     
00031 #define bp2int(p)    round(p*(onehundredbp/100.0))
00032 
00033 /* define image_ptr, image_array & image_limit */
00034 define_array(image);   
00035 
00036 float epdf_width;
00037 float epdf_height;
00038 float epdf_orig_x;
00039 float epdf_orig_y;
00040 integer epdf_selected_page;
00041 integer epdf_num_pages;
00042 integer epdf_page_box;
00043 integer epdf_always_use_pdf_pagebox;
00044 void *epdf_doc;
00045 
00046 static integer new_image_entry(void)
00047 {
00048     alloc_array(image, 1, SMALL_BUF_SIZE);
00049     image_ptr->image_type = IMAGE_TYPE_NONE;
00050     image_ptr->color_type = 0;
00051     image_ptr->num_pages = 0;
00052     image_ptr->x_res = 0;
00053     image_ptr->y_res = 0;
00054     image_ptr->width = 0;
00055     image_ptr->height = 0;
00056     image_ptr->colorspace_ref = 0;
00057     return image_ptr++ - image_array;
00058 }
00059 
00060 integer imagecolor(integer img)
00061 {
00062     return img_color(img);
00063 }
00064 
00065 integer imagewidth(integer img)
00066 {
00067     return img_width(img);
00068 }
00069 
00070 integer imageheight(integer img)
00071 {
00072     return img_height(img);
00073 }
00074 
00075 integer imagexres(integer img)
00076 {
00077     return img_xres(img);
00078 }
00079 
00080 integer imageyres(integer img)
00081 {
00082     return img_yres(img);
00083 }
00084 
00085 boolean ispdfimage(integer img)
00086 {
00087     return img_type(img) == IMAGE_TYPE_PDF;
00088 }
00089 
00090 boolean checkimageb(integer procset)
00091 {
00092     return procset & IMAGE_COLOR_B;
00093 }
00094 
00095 boolean checkimagec(integer procset)
00096 {
00097     return procset & IMAGE_COLOR_C;
00098 }
00099 
00100 boolean checkimagei(integer procset)
00101 {
00102     return procset & IMAGE_COLOR_I;
00103 }
00104 
00105 void updateimageprocset(integer img)
00106 {
00107     pdfimageprocset |= img_color(img);
00108 }
00109 
00110 integer epdforigx(integer img)
00111 {
00112     return pdf_ptr(img)->orig_x;
00113 }
00114 
00115 integer epdforigy(integer img)
00116 {
00117     return pdf_ptr(img)->orig_y;
00118 }
00119 
00120 integer imagepages(integer img)
00121 {
00122     return img_pages(img);
00123 }
00124 
00125 integer imagecolordepth(integer img)
00126 {
00127     switch (img_type(img)) {
00128     case IMAGE_TYPE_PNG:
00129         return png_info(img)->bit_depth;
00130     case IMAGE_TYPE_JPG:
00131         return jpg_ptr(img)->bits_per_component;
00132     case IMAGE_TYPE_PDF:
00133         return 0;
00134     default:
00135         pdftex_fail("unknown type of image");
00136     }
00137 }
00138 
00139 /*
00140   Patch ImageTypeDetection 2003/02/08 by Heiko Oberdiek.
00141 
00142   Function "readimage" performs some basic initializations.
00143   Then it looks at the file extension to determine the
00144   image type and calls specific code/functions.
00145     The main disadvantage is that standard file extensions
00146   have to be used, otherwise pdfTeX is not able to detect
00147   the correct image type.
00148 
00149   The patch now looks at the file header first regardless of
00150   the file extension. This is implemented in function
00151   "checktypebyheader". If this check fails, the traditional
00152   test of standard file extension is tried, done in function
00153   "checktypebyextension".
00154 
00155   Magic headers:
00156 
00157   * "PNG (Portable Network Graphics) Specification", Version 1.2
00158     (http://www.libpng.org/pub/png):
00159 
00160   |   3.1. PNG file signature
00161   |
00162   |      The first eight bytes of a PNG file always contain the following
00163   |      (decimal) values:
00164   |
00165   |         137 80 78 71 13 10 26 10
00166 
00167   Translation to C: "\x89PNG\r\n\x1A\n"
00168 
00169   * "JPEG File Interchange Format", Version 1.02:
00170 
00171   | o you can identify a JFIF file by looking for the following
00172   |   sequence: X'FF', SOI X'FF', APP0, <2 bytes to be skipped>,
00173   |   "JFIF", X'00'.
00174 
00175   Function "checktypebyheader" only looks at the first two bytes:
00176     "\xFF\xD8"
00177 
00178   * "PDF Reference", third edition:
00179     * The first line should contain "%PDF-1.0" until "%PDF-1.4"
00180       (section 3.4.1 "File Header").
00181     * The "implementation notes" say:
00182 
00183     | 3.4.1,  File Header
00184     |   12. Acrobat viewers require only that the header appear
00185     |       somewhere within the first 1024 bytes of the file.
00186     |   13. Acrobat viewers will also accept a header of the form
00187     |           %!PS-Adobe-N.n PDF-M.m
00188 
00189     The check in function "checktypebyheader" only implements
00190     the first issue. The implementation notes are not considered.
00191     Therefore files with garbage at start of file must have the
00192     standard extension.
00193 
00194     Functions "checktypebyheader" and "checktypebyextension":
00195     img_type(img) is set to IMAGE_TYPE_NONE by new_image_entry().
00196     Both functions tries to detect a type and set img_type(img).
00197     Thus a value other than IMAGE_TYPE_NONE indicates that a
00198     type is found.
00199 */
00200 
00201 #define HEADER_JPG "\xFF\xD8"
00202 #define HEADER_PNG "\x89PNG\r\n\x1A\n"
00203 #define HEADER_PDF "%PDF-1."
00204 #define MAX_HEADER (sizeof(HEADER_PNG)-1)
00205 static void checktypebyheader(integer img)
00206 {
00207     int i;
00208     FILE *file = NULL;
00209     char header[MAX_HEADER];
00210 
00211     if (img_type(img) != IMAGE_TYPE_NONE) /* nothing to do */
00212         return;
00213 
00214     /* read the header */
00215     file = xfopen(img_name(img), FOPEN_RBIN_MODE);
00216     for (i=0; i<MAX_HEADER; i++) {
00217         header[i] = xgetc(file);
00218         if (feof(file))
00219             pdftex_fail("reading image file failed");
00220     }
00221     xfclose(file, img_name(img));
00222 
00223     /* tests */
00224     if (strncmp(header, HEADER_JPG, sizeof(HEADER_JPG)-1) == 0)
00225         img_type(img) = IMAGE_TYPE_JPG;
00226     else if (strncmp(header, HEADER_PNG, sizeof(HEADER_PNG)-1) == 0)
00227         img_type(img) = IMAGE_TYPE_PNG;
00228     else if (strncmp(header, HEADER_PDF, sizeof(HEADER_PDF)-1) == 0)
00229         img_type(img) = IMAGE_TYPE_PDF;
00230 }
00231 
00232 static void checktypebyextension(integer img)
00233 {
00234     char *image_suffix;
00235 
00236     if (img_type(img) != IMAGE_TYPE_NONE) /* nothing to do */
00237         return;
00238     /* tests */
00239     if ((image_suffix = strrchr(cur_file_name, '.')) == 0)
00240         img_type(img) = IMAGE_TYPE_NONE;
00241     else if (strcasecmp(image_suffix, ".pdf") == 0)
00242         img_type(img) = IMAGE_TYPE_PDF;
00243     else if (strcasecmp(image_suffix, ".png") == 0)
00244         img_type(img) = IMAGE_TYPE_PNG;
00245     else if (strcasecmp(image_suffix, ".jpg") == 0 ||
00246              strcasecmp(image_suffix, ".jpeg") == 0)
00247         img_type(img) = IMAGE_TYPE_JPG;
00248 }
00249 
00250 integer readimage(strnumber s, integer page_num, strnumber page_name, integer colorspace,
00251                   integer pdfversion, integer pdfoptionalwaysusepdfpagebox,
00252                   integer pdf_option_pdf_inclusion_errorlevel)
00253 {
00254     char *dest = NULL;
00255     integer img = new_image_entry();
00256     img_colorspace_ref(img) = colorspace;
00257 
00258     /* need to allocate new string as makecstring's buffer is 
00259        already used by cur_file_name */
00260     if (page_name != 0)
00261       dest = xstrdup(makecstring(page_name));
00262     cur_file_name = makecstring(s);
00263 #ifdef WIN32
00264     /* unquote file name */
00265     if (*cur_file_name == '"') {
00266       char *p = cur_file_name;
00267       char *q = cur_file_name;
00268       while (p && *p) {
00269     *q = (*p == '"' ? *(++p) : *p);
00270     p++, q++;
00271       }
00272       *q = '\0';
00273     }
00274     fprintf(stderr, " %s\n", cur_file_name);
00275 #endif
00276     img_name(img) = kpse_find_file(cur_file_name, kpse_tex_format, true);
00277     if (img_name(img) == NULL)
00278         pdftex_fail("cannot find image file");
00279     /* type checks */
00280     checktypebyheader(img);
00281     checktypebyextension(img);
00282     /* read image */
00283     switch (img_type(img)) {
00284     case IMAGE_TYPE_PDF:
00285         pdf_ptr(img) = xtalloc(1, pdf_image_struct);
00286         pdf_ptr(img)->page_box = pdflastpdfboxspec;
00287         pdf_ptr(img)->always_use_pdfpagebox = pdfoptionalwaysusepdfpagebox;
00288         page_num = read_pdf_info(img_name(img), dest, page_num, 
00289                                      pdfversion, pdfoptionalwaysusepdfpagebox,
00290                                      pdf_option_pdf_inclusion_errorlevel);
00291         img_width(img) = bp2int(epdf_width);
00292         img_height(img) = bp2int(epdf_height);
00293         img_pages(img) = epdf_num_pages;
00294         pdf_ptr(img)->orig_x = bp2int(epdf_orig_x);
00295         pdf_ptr(img)->orig_y = bp2int(epdf_orig_y);
00296         pdf_ptr(img)->selected_page = page_num;
00297         pdf_ptr(img)->doc = epdf_doc;
00298         break;
00299     case IMAGE_TYPE_PNG:
00300         img_pages(img) = 1;
00301         read_png_info(img);
00302         break;
00303     case IMAGE_TYPE_JPG:
00304         jpg_ptr(img) = xtalloc(1, JPG_IMAGE_INFO);
00305         img_pages(img) = 1;
00306         read_jpg_info(img);
00307         break;
00308     default:
00309         pdftex_fail("unknown type of image");
00310     }
00311     xfree(dest);
00312     cur_file_name = NULL;
00313     return img;
00314 }
00315 
00316 void writeimage(integer img)
00317 {
00318     cur_file_name = img_name(img);
00319     tex_printf(" <%s", img_name(img));
00320     switch (img_type(img)) {
00321     case IMAGE_TYPE_PNG:
00322         write_png(img);
00323         break;
00324     case IMAGE_TYPE_JPG:
00325         write_jpg(img);
00326         break;
00327     case IMAGE_TYPE_PDF:
00328         epdf_doc = pdf_ptr(img)->doc;
00329         epdf_selected_page = pdf_ptr(img)->selected_page;
00330         epdf_page_box = pdf_ptr(img)->page_box;
00331         epdf_always_use_pdf_pagebox = pdf_ptr(img)->always_use_pdfpagebox;
00332         write_epdf();
00333         break;
00334     default:
00335         pdftex_fail("unknown type of image");
00336     }
00337     tex_printf(">");
00338     cur_file_name = NULL;
00339 }
00340 
00341 void deleteimage(integer img)
00342 {
00343     switch (img_type(img)) {
00344     case IMAGE_TYPE_PDF:
00345         epdf_doc = pdf_ptr(img)->doc;
00346         epdf_delete();
00347         break;
00348     case IMAGE_TYPE_PNG:
00349         xfclose(png_ptr(img)->io_ptr, cur_file_name);
00350         png_destroy_read_struct(&(png_ptr(img)), &(png_info(img)), NULL);
00351         break;
00352     case IMAGE_TYPE_JPG:
00353         xfclose(jpg_ptr(img)->file, cur_file_name);
00354         break;
00355     default:
00356         pdftex_fail("unknown type of image");
00357     }
00358     xfree(img_name(img));
00359     return;
00360 }
00361 
00362 void img_free() 
00363 {
00364     xfree(image_array);
00365 }