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