png2pnm.c revision ca2bf81b02c99afa2e76b3b2c6eb232c239221e0
1893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/*
2893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *  png2pnm.c --- conversion from PNG-file to PGM/PPM-file
3893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *  copyright (C) 1999 by Willem van Schaik <willem@schaik.com>
4893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *
5893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *  version 1.0 - 1999.10.15 - First version.
6893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *
7893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *  Permission to use, copy, modify, and distribute this software and
8893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *  its documentation for any purpose and without fee is hereby granted,
9893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *  provided that the above copyright notice appear in all copies and
10893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *  that both that copyright notice and this permission notice appear in
11893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *  supporting documentation. This software is provided "as is" without
12893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *  express or implied warranty.
13893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project */
14893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
15893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#include <stdio.h>
16893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#include <stdlib.h>
17893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef __TURBOC__
18893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#include <mem.h>
19893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#include <fcntl.h>
20893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
21ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik#include <zlib.h>
22893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
23893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifndef BOOL
24893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#define BOOL unsigned char
25893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
26893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifndef TRUE
27893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#define TRUE (BOOL) 1
28893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
29893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifndef FALSE
30893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#define FALSE (BOOL) 0
31893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
32893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
33893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef __TURBOC__
34893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#define STDIN  0
35893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#define STDOUT 1
36893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#define STDERR 2
37893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
38893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
39893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* to make png2pnm verbose so we can find problems (needs to be before png.h) */
40893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifndef PNG_DEBUG
41893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#define PNG_DEBUG 0
42893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
43893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
44893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#include "png.h"
45893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
46893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* Define png_jmpbuf() in case we are using a pre-1.0.6 version of libpng */
47893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifndef png_jmpbuf
48893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#  define png_jmpbuf(png_ptr) ((png_ptr)->jmpbuf)
49893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
50893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
51893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* function prototypes */
52893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
53893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectint  main (int argc, char *argv[]);
54893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid usage ();
55893912bfc2683463dc3e2c445336752d012563d3The Android Open Source ProjectBOOL png2pnm (FILE *png_file, FILE *pnm_file, FILE *alpha_file, BOOL raw, BOOL alpha);
56893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
57893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/*
58893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *  main
59893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project */
60893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
61893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectint main(int argc, char *argv[])
62893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
63893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  FILE *fp_rd = stdin;
64893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  FILE *fp_wr = stdout;
65893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  FILE *fp_al = NULL;
66893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  BOOL raw = TRUE;
67893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  BOOL alpha = FALSE;
68893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  int argi;
69893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
70893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  for (argi = 1; argi < argc; argi++)
71893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  {
72893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (argv[argi][0] == '-')
73893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    {
74893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      switch (argv[argi][1])
75893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
76893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        case 'n':
77893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          raw = FALSE;
78893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          break;
79893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        case 'r':
80893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          raw = TRUE;
81893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          break;
82893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        case 'a':
83893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          alpha = TRUE;
84893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          argi++;
85893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          if ((fp_al = fopen (argv[argi], "wb")) == NULL)
86893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          {
87893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            fprintf (stderr, "PNM2PNG\n");
88893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            fprintf (stderr, "Error:  can not create alpha-channel file %s\n", argv[argi]);
89893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            exit (1);
90893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          }
91893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          break;
92893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        case 'h':
93893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        case '?':
94893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          usage();
95893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          exit(0);
96893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          break;
97893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        default:
98893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          fprintf (stderr, "PNG2PNM\n");
99893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          fprintf (stderr, "Error:  unknown option %s\n", argv[argi]);
100893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          usage();
101893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          exit(1);
102893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          break;
103893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      } /* end switch */
104893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
105893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    else if (fp_rd == stdin)
106893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    {
107893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      if ((fp_rd = fopen (argv[argi], "rb")) == NULL)
108893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
109893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project             fprintf (stderr, "PNG2PNM\n");
110893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            fprintf (stderr, "Error:  file %s does not exist\n", argv[argi]);
111893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            exit (1);
112893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
113893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
114893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    else if (fp_wr == stdout)
115893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    {
116893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      if ((fp_wr = fopen (argv[argi], "wb")) == NULL)
117893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
118893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        fprintf (stderr, "PNG2PNM\n");
119893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        fprintf (stderr, "Error:  can not create file %s\n", argv[argi]);
120893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        exit (1);
121893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
122893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
123893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    else
124893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    {
125893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      fprintf (stderr, "PNG2PNM\n");
126893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      fprintf (stderr, "Error:  too many parameters\n");
127893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      usage();
128893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      exit(1);
129893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
130893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  } /* end for */
131893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
132893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef __TURBOC__
133893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  /* set stdin/stdout if required to binary */
134893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  if (fp_rd == stdin)
135893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  {
136893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    setmode (STDIN, O_BINARY);
137893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  }
138893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  if ((raw) && (fp_wr == stdout))
139893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  {
140893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    setmode (STDOUT, O_BINARY);
141893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  }
142893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
143893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
144893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  /* call the conversion program itself */
145893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  if (png2pnm (fp_rd, fp_wr, fp_al, raw, alpha) == FALSE)
146893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  {
147893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    fprintf (stderr, "PNG2PNM\n");
148ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik    fprintf (stderr, "Error:  unsuccessful conversion of PNG-image\n");
149893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    exit(1);
150893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  }
151893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
152893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  /* close input file */
153893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  fclose (fp_rd);
154893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  /* close output file */
155893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  fclose (fp_wr);
156893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  /* close alpha file */
157893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  if (alpha)
158893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    fclose (fp_al);
159893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
160893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  return 0;
161893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
162893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
163893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/*
164893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *  usage
165893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project */
166893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
167893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid usage()
168893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
169893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  fprintf (stderr, "PNG2PNM\n");
170893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  fprintf (stderr, "   by Willem van Schaik, 1999\n");
171893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef __TURBOC__
172893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  fprintf (stderr, "   for Turbo-C and Borland-C compilers\n");
173893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#else
174893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  fprintf (stderr, "   for Linux (and Unix) compilers\n");
175893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
176893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  fprintf (stderr, "Usage:  png2pnm [options] <file>.png [<file>.pnm]\n");
177893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  fprintf (stderr, "   or:  ... | png2pnm [options]\n");
178893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  fprintf (stderr, "Options:\n");
179893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  fprintf (stderr, "   -r[aw]   write pnm-file in binary format (P4/P5/P6) (default)\n");
180893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  fprintf (stderr, "   -n[oraw] write pnm-file in ascii format (P1/P2/P3)\n");
181893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  fprintf (stderr, "   -a[lpha] <file>.pgm write PNG alpha channel as pgm-file\n");
182893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  fprintf (stderr, "   -h | -?  print this help-information\n");
183893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
184893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
185893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/*
186893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *  png2pnm
187893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project */
188893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
189893912bfc2683463dc3e2c445336752d012563d3The Android Open Source ProjectBOOL png2pnm (FILE *png_file, FILE *pnm_file, FILE *alpha_file, BOOL raw, BOOL alpha)
190893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
191893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  png_struct    *png_ptr = NULL;
192ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik  png_info        *info_ptr = NULL;
193893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  png_byte      buf[8];
194893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  png_byte      *png_pixels = NULL;
195893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  png_byte      **row_pointers = NULL;
196893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  png_byte      *pix_ptr = NULL;
197893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  png_uint_32   row_bytes;
198893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
199893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  png_uint_32   width;
200893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  png_uint_32   height;
201893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  int           bit_depth;
202893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  int           channels;
203893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  int           color_type;
204893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  int           alpha_present;
205893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  int           row, col;
206893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  int           ret;
207893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  int           i;
208893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  long          dep_16;
209893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
210893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  /* read and check signature in PNG file */
211893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  ret = fread (buf, 1, 8, png_file);
212893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  if (ret != 8)
213893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    return FALSE;
214893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
215ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik  ret = png_sig_cmp (buf, 0, 8);
216ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik  if (ret)
217893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    return FALSE;
218893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
219893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  /* create png and info structures */
220893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
221893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING,
222893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    NULL, NULL, NULL);
223893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  if (!png_ptr)
224893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    return FALSE;   /* out of memory */
225893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
226893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  info_ptr = png_create_info_struct (png_ptr);
227893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  if (!info_ptr)
228893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  {
229893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    png_destroy_read_struct (&png_ptr, NULL, NULL);
230893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    return FALSE;   /* out of memory */
231893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  }
232893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
233893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  if (setjmp (png_jmpbuf(png_ptr)))
234893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  {
235893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
236893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    return FALSE;
237893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  }
238893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
239893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  /* set up the input control for C streams */
240893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  png_init_io (png_ptr, png_file);
241893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  png_set_sig_bytes (png_ptr, 8);  /* we already read the 8 signature bytes */
242893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
243893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  /* read the file information */
244893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  png_read_info (png_ptr, info_ptr);
245893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
246893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  /* get size and bit-depth of the PNG-image */
247893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  png_get_IHDR (png_ptr, info_ptr,
248893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    &width, &height, &bit_depth, &color_type,
249893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    NULL, NULL, NULL);
250893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
251893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  /* set-up the transformations */
252893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
253893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  /* transform paletted images into full-color rgb */
254893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  if (color_type == PNG_COLOR_TYPE_PALETTE)
255893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    png_set_expand (png_ptr);
256893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  /* expand images to bit-depth 8 (only applicable for grayscale images) */
257893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
258893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    png_set_expand (png_ptr);
259893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  /* transform transparency maps into full alpha-channel */
260893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  if (png_get_valid (png_ptr, info_ptr, PNG_INFO_tRNS))
261893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    png_set_expand (png_ptr);
262893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
263893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef NJET
264893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  /* downgrade 16-bit images to 8 bit */
265893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  if (bit_depth == 16)
266893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    png_set_strip_16 (png_ptr);
267893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  /* transform grayscale images into full-color */
268893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  if (color_type == PNG_COLOR_TYPE_GRAY ||
269893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
270893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    png_set_gray_to_rgb (png_ptr);
271893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  /* only if file has a file gamma, we do a correction */
272893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  if (png_get_gAMA (png_ptr, info_ptr, &file_gamma))
273893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    png_set_gamma (png_ptr, (double) 2.2, file_gamma);
274893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
275893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
276893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  /* all transformations have been registered; now update info_ptr data,
277893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   * get rowbytes and channels, and allocate image memory */
278893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
279893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  png_read_update_info (png_ptr, info_ptr);
280893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
281893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  /* get the new color-type and bit-depth (after expansion/stripping) */
282893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  png_get_IHDR (png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,
283893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    NULL, NULL, NULL);
284893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
285893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  /* check for 16-bit files */
286893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  if (bit_depth == 16)
287893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  {
288893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    raw = FALSE;
289893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef __TURBOC__
290893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    pnm_file->flags &= ~((unsigned) _F_BIN);
291893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
292893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  }
293893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
294893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  /* calculate new number of channels and store alpha-presence */
295893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  if (color_type == PNG_COLOR_TYPE_GRAY)
296893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    channels = 1;
297893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  else if (color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
298893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    channels = 2;
299893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  else if (color_type == PNG_COLOR_TYPE_RGB)
300893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    channels = 3;
301893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  else if (color_type == PNG_COLOR_TYPE_RGB_ALPHA)
302893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    channels = 4;
303893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  else
304893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    channels = 0; /* should never happen */
305893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  alpha_present = (channels - 1) % 2;
306893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
307893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  /* check if alpha is expected to be present in file */
308893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  if (alpha && !alpha_present)
309893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  {
310893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    fprintf (stderr, "PNG2PNM\n");
311893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    fprintf (stderr, "Error:  PNG-file doesn't contain alpha channel\n");
312893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    exit (1);
313893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  }
314893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
315893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  /* row_bytes is the width x number of channels x (bit-depth / 8) */
316893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  row_bytes = png_get_rowbytes (png_ptr, info_ptr);
317893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
318893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  if ((png_pixels = (png_byte *) malloc (row_bytes * height * sizeof (png_byte))) == NULL) {
319893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
320893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    return FALSE;
321893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  }
322893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
323893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  if ((row_pointers = (png_byte **) malloc (height * sizeof (png_bytep))) == NULL)
324893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  {
325893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
326893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    free (png_pixels);
327893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    png_pixels = NULL;
328893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    return FALSE;
329893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  }
330893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
331893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  /* set the individual row_pointers to point at the correct offsets */
332893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  for (i = 0; i < (height); i++)
333893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    row_pointers[i] = png_pixels + i * row_bytes;
334893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
335893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  /* now we can go ahead and just read the whole image */
336893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  png_read_image (png_ptr, row_pointers);
337893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
338893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  /* read rest of file, and get additional chunks in info_ptr - REQUIRED */
339893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  png_read_end (png_ptr, info_ptr);
340893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
341893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  /* clean up after the read, and free any memory allocated - REQUIRED */
342893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  png_destroy_read_struct (&png_ptr, &info_ptr, (png_infopp) NULL);
343893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
344893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  /* write header of PNM file */
345893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
346893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  if ((color_type == PNG_COLOR_TYPE_GRAY) ||
347893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      (color_type == PNG_COLOR_TYPE_GRAY_ALPHA))
348893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  {
349893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    fprintf (pnm_file, "%s\n", (raw) ? "P5" : "P2");
350893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    fprintf (pnm_file, "%d %d\n", (int) width, (int) height);
351893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    fprintf (pnm_file, "%ld\n", ((1L << (int) bit_depth) - 1L));
352893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  }
353893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  else if ((color_type == PNG_COLOR_TYPE_RGB) ||
354893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project           (color_type == PNG_COLOR_TYPE_RGB_ALPHA))
355893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  {
356893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    fprintf (pnm_file, "%s\n", (raw) ? "P6" : "P3");
357893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    fprintf (pnm_file, "%d %d\n", (int) width, (int) height);
358893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    fprintf (pnm_file, "%ld\n", ((1L << (int) bit_depth) - 1L));
359893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  }
360893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
361893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  /* write header of PGM file with alpha channel */
362893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
363893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  if ((alpha) &&
364893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      ((color_type == PNG_COLOR_TYPE_GRAY_ALPHA) ||
365893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       (color_type == PNG_COLOR_TYPE_RGB_ALPHA)))
366893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  {
367893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    fprintf (alpha_file, "%s\n", (raw) ? "P5" : "P2");
368893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    fprintf (alpha_file, "%d %d\n", (int) width, (int) height);
369893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    fprintf (alpha_file, "%ld\n", ((1L << (int) bit_depth) - 1L));
370893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  }
371893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
372893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  /* write data to PNM file */
373893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  pix_ptr = png_pixels;
374893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
375893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  for (row = 0; row < height; row++)
376893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  {
377893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    for (col = 0; col < width; col++)
378893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    {
379893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      for (i = 0; i < (channels - alpha_present); i++)
380893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
381893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        if (raw)
382893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          fputc ((int) *pix_ptr++ , pnm_file);
383893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        else
384893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          if (bit_depth == 16){
385ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik            dep_16 = (long) *pix_ptr++;
386893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            fprintf (pnm_file, "%ld ", (dep_16 << 8) + ((long) *pix_ptr++));
387893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          }
388893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          else
389893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            fprintf (pnm_file, "%ld ", (long) *pix_ptr++);
390893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
391893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      if (alpha_present)
392893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
393893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        if (!alpha)
394893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        {
395893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          pix_ptr++; /* alpha */
396893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          if (bit_depth == 16)
397893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            pix_ptr++;
398893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        }
399893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        else /* output alpha-channel as pgm file */
400893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        {
401893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          if (raw)
402893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            fputc ((int) *pix_ptr++ , alpha_file);
403893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          else
404893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            if (bit_depth == 16){
405ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik              dep_16 = (long) *pix_ptr++;
406893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project              fprintf (alpha_file, "%ld ", (dep_16 << 8) + (long) *pix_ptr++);
407ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik            }
408893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            else
409893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project              fprintf (alpha_file, "%ld ", (long) *pix_ptr++);
410893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        }
411893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      } /* if alpha_present */
412893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
413893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      if (!raw)
414893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        if (col % 4 == 3)
415893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          fprintf (pnm_file, "\n");
416893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    } /* end for col */
417893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
418893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (!raw)
419893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      if (col % 4 != 0)
420893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        fprintf (pnm_file, "\n");
421893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  } /* end for row */
422893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
423893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  if (row_pointers != (unsigned char**) NULL)
424893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    free (row_pointers);
425893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  if (png_pixels != (unsigned char*) NULL)
426893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    free (png_pixels);
427893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
428893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  return TRUE;
429893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
430893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} /* end of source */
431893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
432