1893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/*
2893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *  pnm2png.c --- conversion from PBM/PGM/PPM-file to PNG-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#define STDIN  0
34893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#define STDOUT 1
35893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#define STDERR 2
36893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
37893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* to make pnm2png verbose so we can find problems (needs to be before png.h) */
38893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifndef PNG_DEBUG
39893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#define PNG_DEBUG 0
40893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
41893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
42893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#include "png.h"
43893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
44893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* Define png_jmpbuf() in case we are using a pre-1.0.6 version of libpng */
45893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifndef png_jmpbuf
46893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#  define png_jmpbuf(png_ptr) ((png_ptr)->jmpbuf)
47893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
48893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
49893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* function prototypes */
50893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
51893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectint  main (int argc, char *argv[]);
52893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid usage ();
53893912bfc2683463dc3e2c445336752d012563d3The Android Open Source ProjectBOOL pnm2png (FILE *pnm_file, FILE *png_file, FILE *alpha_file, BOOL interlace, BOOL alpha);
54893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid get_token(FILE *pnm_file, char *token);
55893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_uint_32 get_data (FILE *pnm_file, int depth);
56893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_uint_32 get_value (FILE *pnm_file, int depth);
57893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
58893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/*
59893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *  main
60893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project */
61893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
62893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectint main(int argc, char *argv[])
63893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
64893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  FILE *fp_rd = stdin;
65893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  FILE *fp_al = NULL;
66893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  FILE *fp_wr = stdout;
67893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  BOOL interlace = FALSE;
68893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  BOOL alpha = FALSE;
69893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  int argi;
70893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
71893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  for (argi = 1; argi < argc; argi++)
72893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  {
73893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (argv[argi][0] == '-')
74893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    {
75893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      switch (argv[argi][1])
76893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
77893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        case 'i':
78893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          interlace = TRUE;
79893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          break;
80893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        case 'a':
81893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          alpha = TRUE;
82893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          argi++;
83893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          if ((fp_al = fopen (argv[argi], "rb")) == NULL)
84893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          {
85893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            fprintf (stderr, "PNM2PNG\n");
86893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            fprintf (stderr, "Error:  alpha-channel file %s does not exist\n",
87893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               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, "PNM2PNG\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, "PNM2PNG\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, "PNM2PNG\n");
118893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        fprintf (stderr, "Error:  can not create PNG-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, "PNM2PNG\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 to binary, we're reading the PNM always! in binary format */
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 (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 (pnm2png (fp_rd, fp_wr, fp_al, interlace, alpha) == FALSE)
145893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  {
146893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    fprintf (stderr, "PNM2PNG\n");
147893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    fprintf (stderr, "Error:  unsuccessful converting to 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, "PNM2PNG\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:  pnm2png [options] <file>.<pnm> [<file>.png]\n");
176893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  fprintf (stderr, "   or:  ... | pnm2png [options]\n");
177893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  fprintf (stderr, "Options:\n");
178893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  fprintf (stderr, "   -i[nterlace]   write png-file with interlacing on\n");
179893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  fprintf (stderr, "   -a[lpha] <file>.pgm read PNG alpha channel as pgm-file\n");
180893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  fprintf (stderr, "   -h | -?  print this help-information\n");
181893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
182893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
183893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/*
184893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *  pnm2png
185893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project */
186893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
187893912bfc2683463dc3e2c445336752d012563d3The Android Open Source ProjectBOOL pnm2png (FILE *pnm_file, FILE *png_file, FILE *alpha_file, BOOL interlace, BOOL alpha)
188893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
189893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  png_struct    *png_ptr = NULL;
190893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  png_info      *info_ptr = NULL;
191893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  png_byte      *png_pixels = NULL;
192893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  png_byte      **row_pointers = NULL;
193893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  png_byte      *pix_ptr = NULL;
194893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  png_uint_32   row_bytes;
195893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
196893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  char          type_token[16];
197893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  char          width_token[16];
198893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  char          height_token[16];
199893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  char          maxval_token[16];
200893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  int           color_type;
201ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik  unsigned long   ul_width=0, ul_alpha_width=0;
202ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik  unsigned long   ul_height=0, ul_alpha_height=0;
203ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik  unsigned long   ul_maxval=0;
204893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  png_uint_32   width, alpha_width;
205893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  png_uint_32   height, alpha_height;
206893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  png_uint_32   maxval;
207893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  int           bit_depth = 0;
208893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  int           channels;
209893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  int           alpha_depth = 0;
210893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  int           alpha_present;
211893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  int           row, col;
212893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  BOOL          raw, alpha_raw = FALSE;
213ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik#if defined(PNG_WRITE_INVERT_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)
214ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik  BOOL          packed_bitmap = FALSE;
215ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik#endif
216893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  png_uint_32   tmp16;
217893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  int           i;
218893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
219893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  /* read header of PNM file */
220893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
221893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  get_token(pnm_file, type_token);
222893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  if (type_token[0] != 'P')
223893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  {
224893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    return FALSE;
225893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  }
226893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  else if ((type_token[1] == '1') || (type_token[1] == '4'))
227893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  {
228ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik#if defined(PNG_WRITE_INVERT_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)
229893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    raw = (type_token[1] == '4');
230893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    color_type = PNG_COLOR_TYPE_GRAY;
231ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik    get_token(pnm_file, width_token);
232ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik    sscanf (width_token, "%lu", &ul_width);
233ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik    width = (png_uint_32) ul_width;
234ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik    get_token(pnm_file, height_token);
235ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik    sscanf (height_token, "%lu", &ul_height);
236ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik    height = (png_uint_32) ul_height;
237893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    bit_depth = 1;
238ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik    packed_bitmap = TRUE;
239ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik#else
240ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik    fprintf (stderr, "PNM2PNG built without PNG_WRITE_INVERT_SUPPORTED and \n");
241ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik    fprintf (stderr, "PNG_WRITE_PACK_SUPPORTED can't read PBM (P1,P4) files\n");
242ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik#endif
243893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  }
244893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  else if ((type_token[1] == '2') || (type_token[1] == '5'))
245893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  {
246893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    raw = (type_token[1] == '5');
247893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    color_type = PNG_COLOR_TYPE_GRAY;
248893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    get_token(pnm_file, width_token);
249ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik    sscanf (width_token, "%lu", &ul_width);
250ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik    width = (png_uint_32) ul_width;
251893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    get_token(pnm_file, height_token);
252ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik    sscanf (height_token, "%lu", &ul_height);
253ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik    height = (png_uint_32) ul_height;
254893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    get_token(pnm_file, maxval_token);
255ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik    sscanf (maxval_token, "%lu", &ul_maxval);
256ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik    maxval = (png_uint_32) ul_maxval;
257ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik
258893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (maxval <= 1)
259893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      bit_depth = 1;
260893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    else if (maxval <= 3)
261893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      bit_depth = 2;
262893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    else if (maxval <= 15)
263893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      bit_depth = 4;
264893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    else if (maxval <= 255)
265893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      bit_depth = 8;
266893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    else /* if (maxval <= 65535) */
267893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      bit_depth = 16;
268893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  }
269893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  else if ((type_token[1] == '3') || (type_token[1] == '6'))
270893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  {
271893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    raw = (type_token[1] == '6');
272893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    color_type = PNG_COLOR_TYPE_RGB;
273893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    get_token(pnm_file, width_token);
274ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik    sscanf (width_token, "%lu", &ul_width);
275ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik    width = (png_uint_32) ul_width;
276893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    get_token(pnm_file, height_token);
277ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik    sscanf (height_token, "%lu", &ul_height);
278ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik    height = (png_uint_32) ul_height;
279893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    get_token(pnm_file, maxval_token);
280ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik    sscanf (maxval_token, "%lu", &ul_maxval);
281ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik    maxval = (png_uint_32) ul_maxval;
282893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (maxval <= 1)
283893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      bit_depth = 1;
284893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    else if (maxval <= 3)
285893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      bit_depth = 2;
286893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    else if (maxval <= 15)
287893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      bit_depth = 4;
288893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    else if (maxval <= 255)
289893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      bit_depth = 8;
290893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    else /* if (maxval <= 65535) */
291893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      bit_depth = 16;
292893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  }
293893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  else
294893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  {
295893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    return FALSE;
296893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  }
297893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
298893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  /* read header of PGM file with alpha channel */
299893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
300893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  if (alpha)
301893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  {
302893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (color_type == PNG_COLOR_TYPE_GRAY)
303893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      color_type = PNG_COLOR_TYPE_GRAY_ALPHA;
304893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (color_type == PNG_COLOR_TYPE_RGB)
305893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      color_type = PNG_COLOR_TYPE_RGB_ALPHA;
306893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
307893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    get_token(alpha_file, type_token);
308893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if (type_token[0] != 'P')
309893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    {
310893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      return FALSE;
311893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
312893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    else if ((type_token[1] == '2') || (type_token[1] == '5'))
313893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    {
314893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      alpha_raw = (type_token[1] == '5');
315893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      get_token(alpha_file, width_token);
316ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik      sscanf (width_token, "%lu", &ul_alpha_width);
317ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik      alpha_width=(png_uint_32) ul_alpha_width;
318893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      if (alpha_width != width)
319893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        return FALSE;
320893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      get_token(alpha_file, height_token);
321ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik      sscanf (height_token, "%lu", &ul_alpha_height);
322ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik      alpha_height = (png_uint_32) ul_alpha_height;
323893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      if (alpha_height != height)
324893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        return FALSE;
325893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      get_token(alpha_file, maxval_token);
326ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik      sscanf (maxval_token, "%lu", &ul_maxval);
327ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik      maxval = (png_uint_32) ul_maxval;
328893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      if (maxval <= 1)
329893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        alpha_depth = 1;
330893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      else if (maxval <= 3)
331893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        alpha_depth = 2;
332893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      else if (maxval <= 15)
333893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        alpha_depth = 4;
334893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      else if (maxval <= 255)
335893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        alpha_depth = 8;
336893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      else /* if (maxval <= 65535) */
337893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        alpha_depth = 16;
338893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      if (alpha_depth != bit_depth)
339893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        return FALSE;
340893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
341893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    else
342893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    {
343893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      return FALSE;
344893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
345893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  } /* end if alpha */
346893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
347893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  /* calculate the number of channels and store alpha-presence */
348893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  if (color_type == PNG_COLOR_TYPE_GRAY)
349893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    channels = 1;
350893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  else if (color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
351893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    channels = 2;
352893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  else if (color_type == PNG_COLOR_TYPE_RGB)
353893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    channels = 3;
354893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  else if (color_type == PNG_COLOR_TYPE_RGB_ALPHA)
355893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    channels = 4;
356893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  else
357893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    channels = 0; /* should not happen */
358893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
359893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  alpha_present = (channels - 1) % 2;
360893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
361ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik#if defined(PNG_WRITE_INVERT_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)
362ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik  if (packed_bitmap)
363ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik    /* row data is as many bytes as can fit width x channels x bit_depth */
364ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik    row_bytes = (width * channels * bit_depth + 7) / 8;
365ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik  else
366ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik#endif
367ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik    /* row_bytes is the width x number of channels x (bit-depth / 8) */
368ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik    row_bytes = width * channels * ((bit_depth <= 8) ? 1 : 2);
369893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
370893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  if ((png_pixels = (png_byte *) malloc (row_bytes * height * sizeof (png_byte))) == NULL)
371893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    return FALSE;
372893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
373893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  /* read data from PNM file */
374893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  pix_ptr = png_pixels;
375893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
376893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  for (row = 0; row < height; row++)
377893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  {
378ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik#if defined(PNG_WRITE_INVERT_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)
379ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik    if (packed_bitmap) {
380ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik      for (i = 0; i < row_bytes; i++)
381ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik        /* png supports this format natively so no conversion is needed */
382ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik        *pix_ptr++ = get_data (pnm_file, 8);
383ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik    } else
384ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik#endif
385893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    {
386ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik      for (col = 0; col < width; col++)
387893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
388ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik        for (i = 0; i < (channels - alpha_present); i++)
389ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik        {
390ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik          if (raw)
391ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik            *pix_ptr++ = get_data (pnm_file, bit_depth);
392893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          else
393ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik            if (bit_depth <= 8)
394ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik              *pix_ptr++ = get_value (pnm_file, bit_depth);
395ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik            else
396ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik            {
397ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik              tmp16 = get_value (pnm_file, bit_depth);
398ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik              *pix_ptr = (png_byte) ((tmp16 >> 8) & 0xFF);
399ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik              pix_ptr++;
400ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik              *pix_ptr = (png_byte) (tmp16 & 0xFF);
401ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik              pix_ptr++;
402ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik            }
403ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik        }
404ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik
405ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik        if (alpha) /* read alpha-channel from pgm file */
406ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik        {
407ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik          if (alpha_raw)
408ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik            *pix_ptr++ = get_data (alpha_file, alpha_depth);
409893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          else
410ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik            if (alpha_depth <= 8)
411ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik              *pix_ptr++ = get_value (alpha_file, bit_depth);
412ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik            else
413ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik            {
414ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik              tmp16 = get_value (alpha_file, bit_depth);
415ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik              *pix_ptr++ = (png_byte) ((tmp16 >> 8) & 0xFF);
416ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik              *pix_ptr++ = (png_byte) (tmp16 & 0xFF);
417ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik            }
418ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik        } /* if alpha */
419ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik      } /* if packed_bitmap */
420893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    } /* end for col */
421893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  } /* end for row */
422893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
423893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  /* prepare the standard PNG structures */
424893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  png_ptr = png_create_write_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
425893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  if (!png_ptr)
426893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  {
427893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    return FALSE;
428893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  }
429893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  info_ptr = png_create_info_struct (png_ptr);
430893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  if (!info_ptr)
431893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  {
432893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    png_destroy_write_struct (&png_ptr, (png_infopp) NULL);
433893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    return FALSE;
434893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  }
435893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
436ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik#if defined(PNG_WRITE_INVERT_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)
437ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik  if (packed_bitmap == TRUE)
438ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik  {
439ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik    png_set_packing (png_ptr);
440ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik    png_set_invert_mono (png_ptr);
441ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik  }
442ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik#endif
443ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik
444893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  /* setjmp() must be called in every function that calls a PNG-reading libpng function */
445893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  if (setjmp (png_jmpbuf(png_ptr)))
446893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  {
447893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    png_destroy_write_struct (&png_ptr, (png_infopp) NULL);
448893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    return FALSE;
449893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  }
450893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
451893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  /* initialize the png structure */
452893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  png_init_io (png_ptr, png_file);
453893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
454893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  /* we're going to write more or less the same PNG as the input file */
455893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  png_set_IHDR (png_ptr, info_ptr, width, height, bit_depth, color_type,
456893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    (!interlace) ? PNG_INTERLACE_NONE : PNG_INTERLACE_ADAM7,
457893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
458893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
459893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  /* write the file header information */
460893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  png_write_info (png_ptr, info_ptr);
461893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
462893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  /* if needed we will allocate memory for an new array of row-pointers */
463893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  if (row_pointers == (unsigned char**) NULL)
464893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  {
465893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    if ((row_pointers = (png_byte **) malloc (height * sizeof (png_bytep))) == NULL)
466893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    {
467893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_destroy_write_struct (&png_ptr, (png_infopp) NULL);
468893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      return FALSE;
469893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    }
470893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  }
471893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
472893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  /* set the individual row_pointers to point at the correct offsets */
473893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  for (i = 0; i < (height); i++)
474893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    row_pointers[i] = png_pixels + i * row_bytes;
475893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
476893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  /* write out the entire image data in one call */
477893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  png_write_image (png_ptr, row_pointers);
478893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
479893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  /* write the additional chuncks to the PNG file (not really needed) */
480893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  png_write_end (png_ptr, info_ptr);
481893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
482893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  /* clean up after the write, and free any memory allocated */
483893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  png_destroy_write_struct (&png_ptr, (png_infopp) NULL);
484893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
485893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  if (row_pointers != (unsigned char**) NULL)
486893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    free (row_pointers);
487893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  if (png_pixels != (unsigned char*) NULL)
488893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    free (png_pixels);
489893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
490893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  return TRUE;
491893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} /* end of pnm2png */
492893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
493893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/*
494893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * get_token() - gets the first string after whitespace
495893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project */
496893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
497893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid get_token(FILE *pnm_file, char *token)
498893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
499893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  int i = 0;
500ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik  int ret;
501893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
502ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik  /* remove white-space and comment lines */
503893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  do
504893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  {
505ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik    ret = fgetc(pnm_file);
506ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik    if (ret == '#') {
507ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik      /* the rest of this line is a comment */
508ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik      do
509ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik      {
510ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik        ret = fgetc(pnm_file);
511ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik      }
512ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik      while ((ret != '\n') && (ret != '\r') && (ret != EOF));
513ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik    }
514ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik    if (ret == EOF) break;
515ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik    token[i] = (unsigned char) ret;
516893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  }
517893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  while ((token[i] == '\n') || (token[i] == '\r') || (token[i] == ' '));
518893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
519893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  /* read string */
520893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  do
521893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  {
522ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik    ret = fgetc(pnm_file);
523ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik    if (ret == EOF) break;
524893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    i++;
525ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik    token[i] = (unsigned char) ret;
526893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  }
527893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  while ((token[i] != '\n') && (token[i] != '\r') && (token[i] != ' '));
528893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
529893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  token[i] = '\0';
530893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
531893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  return;
532893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
533893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
534893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/*
535893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * get_data() - takes first byte and converts into next pixel value,
536893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *        taking as much bits as defined by bit-depth and
537893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *        using the bit-depth to fill up a byte (0Ah -> AAh)
538893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project */
539893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
540893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_uint_32 get_data (FILE *pnm_file, int depth)
541893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
542893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  static int bits_left = 0;
543893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  static int old_value = 0;
544893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  static int mask = 0;
545893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  int i;
546893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  png_uint_32 ret_value;
547893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
548893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  if (mask == 0)
549893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    for (i = 0; i < depth; i++)
550893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      mask = (mask >> 1) | 0x80;
551893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
552893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  if (bits_left <= 0)
553893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  {
554893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    old_value = fgetc (pnm_file);
555893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    bits_left = 8;
556893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  }
557893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
558893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  ret_value = old_value & mask;
559893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  for (i = 1; i < (8 / depth); i++)
560893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    ret_value = ret_value || (ret_value >> depth);
561893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
562893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  old_value = (old_value << depth) & 0xFF;
563893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  bits_left -= depth;
564893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
565893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  return ret_value;
566893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
567893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
568893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/*
569893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * get_value() - takes first (numeric) string and converts into number,
570893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *         using the bit-depth to fill up a byte (0Ah -> AAh)
571893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project */
572893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
573893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_uint_32 get_value (FILE *pnm_file, int depth)
574893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
575893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  static png_uint_32 mask = 0;
576893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  png_byte token[16];
577ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik  unsigned long ul_ret_value;
578893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  png_uint_32 ret_value;
579893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  int i = 0;
580893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
581893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  if (mask == 0)
582893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    for (i = 0; i < depth; i++)
583893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      mask = (mask << 1) | 0x01;
584893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
585893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  get_token (pnm_file, (char *) token);
586ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik  sscanf ((const char *) token, "%lu", &ul_ret_value);
587ca2bf81b02c99afa2e76b3b2c6eb232c239221e0Chris Craik  ret_value = (png_uint_32) ul_ret_value;
588893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
589893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  ret_value &= mask;
590893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
591893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  if (depth < 8)
592893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    for (i = 0; i < (8 / depth); i++)
593893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      ret_value = (ret_value << depth) || ret_value;
594893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
595893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project  return ret_value;
596893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
597893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
598893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* end of source */
599893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
600