Back to index

tetex-bin  3.0
pngimage.c
Go to the documentation of this file.
00001 /*  $Header$
00002 
00003     This is dvipdfm, a DVI to PDF translator.
00004     Copyright (C) 1998, 1999 by Mark A. Wicks
00005 
00006     This program 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     This program 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 this program; if not, write to the Free Software
00018     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019     
00020     The author may be contacted via the e-mail address
00021 
00022        mwicks@kettering.edu
00023 */
00024 
00025 #include <stdio.h>
00026 #include <stdlib.h>
00027 #include <kpathsea/config.h>
00028 #include <kpathsea/c-ctype.h>
00029 #include "system.h"
00030 #include "config.h"
00031 #include "mem.h"
00032 #include "pdfobj.h"
00033 
00034 #ifdef HAVE_LIBPNG
00035 #include <png.h>
00036 
00037 #define TMP "/tmp"
00038 
00039 static unsigned char sigbytes[4];
00040 int check_for_png (FILE *png_file) 
00041 {
00042   rewind (png_file);
00043   if (fread (sigbytes, 1, sizeof(sigbytes), png_file) !=
00044       sizeof(sigbytes) ||
00045       (!png_check_sig (sigbytes, sizeof(sigbytes))))
00046     return 0;
00047   else
00048     return 1;
00049 }
00050 
00051 pdf_obj *start_png_image (FILE *file, char *res_name)
00052 {
00053   pdf_obj *result = NULL, *dict = NULL;
00054   png_structp png_ptr;
00055   png_infop info_ptr;
00056   unsigned long width, height;
00057   unsigned bit_depth, color_type;
00058   rewind (file);
00059   if (!(png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING,    
00060                                      NULL, NULL, NULL)) ||
00061       !(info_ptr = png_create_info_struct (png_ptr))) {
00062     fprintf (stderr, "\n\nLibpng failed to initialize\n");
00063     if (png_ptr)
00064       png_destroy_read_struct(&png_ptr, NULL, NULL);
00065     return NULL;
00066   }
00067   png_init_io (png_ptr, file);
00068   /*  png_set_sig_bytes (png_ptr, 0); */
00069   /* Read PNG header */
00070   png_read_info (png_ptr, info_ptr);
00071   {
00072     png_color_16 default_background;
00073     png_color_16p file_background;
00074 
00075     default_background.red=255; default_background.green=255;
00076     default_background.blue=255; default_background.gray=0;
00077     default_background.index = 0;
00078 
00079     width = png_get_image_width(png_ptr, info_ptr);
00080     height = png_get_image_height(png_ptr, info_ptr);
00081     color_type = png_get_color_type(png_ptr, info_ptr);
00082     bit_depth = png_get_bit_depth(png_ptr, info_ptr);
00083     /* Convert paletted images to true color */
00084     if (color_type == PNG_COLOR_TYPE_PALETTE) {
00085       png_set_expand(png_ptr);
00086     }
00087     /* Limit image component depth to 8 bits */
00088     if (bit_depth == 16) {
00089       png_set_strip_16 (png_ptr);
00090     }
00091     if (png_get_bKGD(png_ptr, info_ptr, &file_background)) {
00092       png_set_background(png_ptr, file_background,
00093                       PNG_BACKGROUND_GAMMA_FILE, 1, 1.0);
00094     } else {
00095       png_set_background(png_ptr, &default_background,
00096                       PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
00097     }
00098   }
00099   { /* Read the image in raw RGB format */
00100     int i, rowbytes, pdf_bit_depth;
00101     png_bytep *rows;
00102     png_read_update_info(png_ptr, info_ptr);
00103     rows = NEW (height, png_bytep);
00104     rowbytes = png_get_rowbytes(png_ptr, info_ptr);
00105     for (i=0; i<height; i++) {
00106       rows[i] = NEW (rowbytes, png_byte);
00107     }
00108     png_read_image(png_ptr, rows);
00109     result = pdf_new_stream(STREAM_COMPRESS);
00110     dict = pdf_stream_dict(result);
00111     pdf_add_dict (dict, pdf_new_name ("Width"),
00112                 pdf_new_number(width));
00113     pdf_add_dict (dict, pdf_new_name ("Height"),
00114                 pdf_new_number(height));
00115     if (color_type == PNG_COLOR_TYPE_GRAY) {
00116       pdf_bit_depth = bit_depth;
00117     } else {
00118       pdf_bit_depth = 8;
00119     }
00120     pdf_add_dict (dict, pdf_new_name ("BitsPerComponent"),
00121                 pdf_new_number(pdf_bit_depth));
00122     if (color_type == PNG_COLOR_TYPE_GRAY ||
00123        color_type == PNG_COLOR_TYPE_GRAY_ALPHA) {
00124       pdf_add_dict (dict, pdf_new_name ("ColorSpace"),
00125                   pdf_new_name ("DeviceGray"));
00126     } else{
00127       pdf_add_dict (dict, pdf_new_name ("ColorSpace"),
00128                   pdf_new_name ("DeviceRGB"));
00129     }
00130     for (i=0; i<height; i++) {
00131       pdf_add_stream (result, (char *) rows[i], rowbytes);
00132       RELEASE (rows[i]);
00133     }
00134     RELEASE (rows);
00135   }
00136   { /* Cleanup  */
00137     if (info_ptr)
00138       png_destroy_info_struct(png_ptr, &info_ptr);
00139     if (png_ptr)
00140       png_destroy_read_struct(&png_ptr, NULL, NULL);
00141   }
00142   return result;
00143 }
00144 
00145 #endif /* HAVE_LIBPNG */
00146