~baltix/+junk/irrlicht-test

« back to all changes in this revision

Viewing changes to source/Irrlicht/libpng/contrib/pngminus/pnm2png.c

  • Committer: Mantas Kriaučiūnas
  • Date: 2011-07-18 13:06:25 UTC
  • Revision ID: mantas@akl.lt-20110718130625-c5pvifp61e7kj1ol
Included whole irrlicht SVN libraries to work around launchpad recipe issue with quilt, see https://answers.launchpad.net/launchpad/+question/165193

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *  pnm2png.c --- conversion from PBM/PGM/PPM-file to PNG-file
 
3
 *  copyright (C) 1999 by Willem van Schaik <willem@schaik.com>
 
4
 *
 
5
 *  version 1.0 - 1999.10.15 - First version.
 
6
 *
 
7
 *  Permission to use, copy, modify, and distribute this software and
 
8
 *  its documentation for any purpose and without fee is hereby granted,
 
9
 *  provided that the above copyright notice appear in all copies and
 
10
 *  that both that copyright notice and this permission notice appear in
 
11
 *  supporting documentation. This software is provided "as is" without
 
12
 *  express or implied warranty.
 
13
 */
 
14
 
 
15
#include <stdio.h>
 
16
#include <stdlib.h>
 
17
#ifdef __TURBOC__
 
18
#include <mem.h>
 
19
#include <fcntl.h>
 
20
#endif
 
21
 
 
22
#ifndef BOOL
 
23
#define BOOL unsigned char
 
24
#endif
 
25
#ifndef TRUE
 
26
#define TRUE (BOOL) 1
 
27
#endif
 
28
#ifndef FALSE
 
29
#define FALSE (BOOL) 0
 
30
#endif
 
31
 
 
32
#define STDIN  0
 
33
#define STDOUT 1
 
34
#define STDERR 2
 
35
 
 
36
/* to make pnm2png verbose so we can find problems (needs to be before png.h) */
 
37
#ifndef PNG_DEBUG
 
38
#define PNG_DEBUG 0
 
39
#endif
 
40
 
 
41
#include "png.h"
 
42
 
 
43
/* Define png_jmpbuf() in case we are using a pre-1.0.6 version of libpng */
 
44
#ifndef png_jmpbuf
 
45
#  define png_jmpbuf(png_ptr) ((png_ptr)->jmpbuf)
 
46
#endif
 
47
 
 
48
/* function prototypes */
 
49
 
 
50
int  main (int argc, char *argv[]);
 
51
void usage ();
 
52
BOOL pnm2png (FILE *pnm_file, FILE *png_file, FILE *alpha_file, BOOL interlace, BOOL alpha);
 
53
void get_token(FILE *pnm_file, char *token);
 
54
png_uint_32 get_data (FILE *pnm_file, int depth);
 
55
png_uint_32 get_value (FILE *pnm_file, int depth);
 
56
 
 
57
/*
 
58
 *  main
 
59
 */
 
60
 
 
61
int main(int argc, char *argv[])
 
62
{
 
63
  FILE *fp_rd = stdin;
 
64
  FILE *fp_al = NULL;
 
65
  FILE *fp_wr = stdout;
 
66
  BOOL interlace = FALSE;
 
67
  BOOL alpha = FALSE;
 
68
  int argi;
 
69
 
 
70
  for (argi = 1; argi < argc; argi++)
 
71
  {
 
72
    if (argv[argi][0] == '-')
 
73
    {
 
74
      switch (argv[argi][1])
 
75
      {
 
76
        case 'i':
 
77
          interlace = TRUE;
 
78
          break;
 
79
        case 'a':
 
80
          alpha = TRUE;
 
81
          argi++;
 
82
          if ((fp_al = fopen (argv[argi], "rb")) == NULL)
 
83
          {
 
84
            fprintf (stderr, "PNM2PNG\n");
 
85
            fprintf (stderr, "Error:  alpha-channel file %s does not exist\n",
 
86
               argv[argi]);
 
87
            exit (1);
 
88
          }
 
89
          break;
 
90
        case 'h':
 
91
        case '?':
 
92
          usage();
 
93
          exit(0);
 
94
          break;
 
95
        default:
 
96
          fprintf (stderr, "PNM2PNG\n");
 
97
          fprintf (stderr, "Error:  unknown option %s\n", argv[argi]);
 
98
          usage();
 
99
          exit(1);
 
100
          break;
 
101
      } /* end switch */
 
102
    }
 
103
    else if (fp_rd == stdin)
 
104
    {
 
105
      if ((fp_rd = fopen (argv[argi], "rb")) == NULL)
 
106
      {
 
107
        fprintf (stderr, "PNM2PNG\n");
 
108
        fprintf (stderr, "Error:  file %s does not exist\n", argv[argi]);
 
109
        exit (1);
 
110
      }
 
111
    }
 
112
    else if (fp_wr == stdout)
 
113
    {
 
114
      if ((fp_wr = fopen (argv[argi], "wb")) == NULL)
 
115
      {
 
116
        fprintf (stderr, "PNM2PNG\n");
 
117
        fprintf (stderr, "Error:  can not create PNG-file %s\n", argv[argi]);
 
118
        exit (1);
 
119
      }
 
120
    }
 
121
    else
 
122
    {
 
123
      fprintf (stderr, "PNM2PNG\n");
 
124
      fprintf (stderr, "Error:  too many parameters\n");
 
125
      usage();
 
126
      exit (1);
 
127
    }
 
128
  } /* end for */
 
129
 
 
130
#ifdef __TURBOC__
 
131
  /* set stdin/stdout to binary, we're reading the PNM always! in binary format */
 
132
  if (fp_rd == stdin)
 
133
  {
 
134
    setmode (STDIN, O_BINARY);
 
135
  }
 
136
  if (fp_wr == stdout)
 
137
  {
 
138
    setmode (STDOUT, O_BINARY);
 
139
  }
 
140
#endif
 
141
 
 
142
  /* call the conversion program itself */
 
143
  if (pnm2png (fp_rd, fp_wr, fp_al, interlace, alpha) == FALSE)
 
144
  {
 
145
    fprintf (stderr, "PNM2PNG\n");
 
146
    fprintf (stderr, "Error:  unsuccessful converting to PNG-image\n");
 
147
    exit (1);
 
148
  }
 
149
 
 
150
  /* close input file */
 
151
  fclose (fp_rd);
 
152
  /* close output file */
 
153
  fclose (fp_wr);
 
154
  /* close alpha file */
 
155
  if (alpha)
 
156
    fclose (fp_al);
 
157
 
 
158
  return 0;
 
159
}
 
160
 
 
161
/*
 
162
 *  usage
 
163
 */
 
164
 
 
165
void usage()
 
166
{
 
167
  fprintf (stderr, "PNM2PNG\n");
 
168
  fprintf (stderr, "   by Willem van Schaik, 1999\n");
 
169
#ifdef __TURBOC__
 
170
  fprintf (stderr, "   for Turbo-C and Borland-C compilers\n");
 
171
#else
 
172
  fprintf (stderr, "   for Linux (and Unix) compilers\n");
 
173
#endif
 
174
  fprintf (stderr, "Usage:  pnm2png [options] <file>.<pnm> [<file>.png]\n");
 
175
  fprintf (stderr, "   or:  ... | pnm2png [options]\n");
 
176
  fprintf (stderr, "Options:\n");
 
177
  fprintf (stderr, "   -i[nterlace]   write png-file with interlacing on\n");
 
178
  fprintf (stderr, "   -a[lpha] <file>.pgm read PNG alpha channel as pgm-file\n");
 
179
  fprintf (stderr, "   -h | -?  print this help-information\n");
 
180
}
 
181
 
 
182
/*
 
183
 *  pnm2png
 
184
 */
 
185
 
 
186
BOOL pnm2png (FILE *pnm_file, FILE *png_file, FILE *alpha_file, BOOL interlace, BOOL alpha)
 
187
{
 
188
  png_struct    *png_ptr = NULL;
 
189
  png_info      *info_ptr = NULL;
 
190
  png_byte      *png_pixels = NULL;
 
191
  png_byte      **row_pointers = NULL;
 
192
  png_byte      *pix_ptr = NULL;
 
193
  png_uint_32   row_bytes;
 
194
 
 
195
  char          type_token[16];
 
196
  char          width_token[16];
 
197
  char          height_token[16];
 
198
  char          maxval_token[16];
 
199
  int           color_type;
 
200
  png_uint_32   width, alpha_width;
 
201
  png_uint_32   height, alpha_height;
 
202
  png_uint_32   maxval;
 
203
  int           bit_depth = 0;
 
204
  int           channels;
 
205
  int           alpha_depth = 0;
 
206
  int           alpha_present;
 
207
  int           row, col;
 
208
  BOOL          raw, alpha_raw = FALSE;
 
209
  png_uint_32   tmp16;
 
210
  int           i;
 
211
 
 
212
  /* read header of PNM file */
 
213
 
 
214
  get_token(pnm_file, type_token);
 
215
  if (type_token[0] != 'P')
 
216
  {
 
217
    return FALSE;
 
218
  }
 
219
  else if ((type_token[1] == '1') || (type_token[1] == '4'))
 
220
  {
 
221
    raw = (type_token[1] == '4');
 
222
    color_type = PNG_COLOR_TYPE_GRAY;
 
223
    bit_depth = 1;
 
224
  }
 
225
  else if ((type_token[1] == '2') || (type_token[1] == '5'))
 
226
  {
 
227
    raw = (type_token[1] == '5');
 
228
    color_type = PNG_COLOR_TYPE_GRAY;
 
229
    get_token(pnm_file, width_token);
 
230
    sscanf (width_token, "%lu", &width);
 
231
    get_token(pnm_file, height_token);
 
232
    sscanf (height_token, "%lu", &height);
 
233
    get_token(pnm_file, maxval_token);
 
234
    sscanf (maxval_token, "%lu", &maxval);
 
235
    if (maxval <= 1)
 
236
      bit_depth = 1;
 
237
    else if (maxval <= 3)
 
238
      bit_depth = 2;
 
239
    else if (maxval <= 15)
 
240
      bit_depth = 4;
 
241
    else if (maxval <= 255)
 
242
      bit_depth = 8;
 
243
    else /* if (maxval <= 65535) */
 
244
      bit_depth = 16;
 
245
  }
 
246
  else if ((type_token[1] == '3') || (type_token[1] == '6'))
 
247
  {
 
248
    raw = (type_token[1] == '6');
 
249
    color_type = PNG_COLOR_TYPE_RGB;
 
250
    get_token(pnm_file, width_token);
 
251
    sscanf (width_token, "%lu", &width);
 
252
    get_token(pnm_file, height_token);
 
253
    sscanf (height_token, "%lu", &height);
 
254
    get_token(pnm_file, maxval_token);
 
255
    sscanf (maxval_token, "%lu", &maxval);
 
256
    if (maxval <= 1)
 
257
      bit_depth = 1;
 
258
    else if (maxval <= 3)
 
259
      bit_depth = 2;
 
260
    else if (maxval <= 15)
 
261
      bit_depth = 4;
 
262
    else if (maxval <= 255)
 
263
      bit_depth = 8;
 
264
    else /* if (maxval <= 65535) */
 
265
      bit_depth = 16;
 
266
  }
 
267
  else
 
268
  {
 
269
    return FALSE;
 
270
  }
 
271
 
 
272
  /* read header of PGM file with alpha channel */
 
273
 
 
274
  if (alpha)
 
275
  {
 
276
    if (color_type == PNG_COLOR_TYPE_GRAY)
 
277
      color_type = PNG_COLOR_TYPE_GRAY_ALPHA;
 
278
    if (color_type == PNG_COLOR_TYPE_RGB)
 
279
      color_type = PNG_COLOR_TYPE_RGB_ALPHA;
 
280
 
 
281
    get_token(alpha_file, type_token);
 
282
    if (type_token[0] != 'P')
 
283
    {
 
284
      return FALSE;
 
285
    }
 
286
    else if ((type_token[1] == '2') || (type_token[1] == '5'))
 
287
    {
 
288
      alpha_raw = (type_token[1] == '5');
 
289
      get_token(alpha_file, width_token);
 
290
      sscanf (width_token, "%lu", &alpha_width);
 
291
      if (alpha_width != width)
 
292
        return FALSE;
 
293
      get_token(alpha_file, height_token);
 
294
      sscanf (height_token, "%lu", &alpha_height);
 
295
      if (alpha_height != height)
 
296
        return FALSE;
 
297
      get_token(alpha_file, maxval_token);
 
298
      sscanf (maxval_token, "%lu", &maxval);
 
299
      if (maxval <= 1)
 
300
        alpha_depth = 1;
 
301
      else if (maxval <= 3)
 
302
        alpha_depth = 2;
 
303
      else if (maxval <= 15)
 
304
        alpha_depth = 4;
 
305
      else if (maxval <= 255)
 
306
        alpha_depth = 8;
 
307
      else /* if (maxval <= 65535) */
 
308
        alpha_depth = 16;
 
309
      if (alpha_depth != bit_depth)
 
310
        return FALSE;
 
311
    }
 
312
    else
 
313
    {
 
314
      return FALSE;
 
315
    }
 
316
  } /* end if alpha */
 
317
 
 
318
  /* calculate the number of channels and store alpha-presence */
 
319
  if (color_type == PNG_COLOR_TYPE_GRAY)
 
320
    channels = 1;
 
321
  else if (color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
 
322
    channels = 2;
 
323
  else if (color_type == PNG_COLOR_TYPE_RGB)
 
324
    channels = 3;
 
325
  else if (color_type == PNG_COLOR_TYPE_RGB_ALPHA)
 
326
    channels = 4;
 
327
  else
 
328
    channels = 0; /* should not happen */
 
329
 
 
330
  alpha_present = (channels - 1) % 2;
 
331
 
 
332
  /* row_bytes is the width x number of channels x (bit-depth / 8) */
 
333
  row_bytes = width * channels * ((bit_depth <= 8) ? 1 : 2);
 
334
 
 
335
  if ((png_pixels = (png_byte *) malloc (row_bytes * height * sizeof (png_byte))) == NULL)
 
336
    return FALSE;
 
337
 
 
338
  /* read data from PNM file */
 
339
  pix_ptr = png_pixels;
 
340
 
 
341
  for (row = 0; row < height; row++)
 
342
  {
 
343
    for (col = 0; col < width; col++)
 
344
    {
 
345
      for (i = 0; i < (channels - alpha_present); i++)
 
346
      {
 
347
        if (raw)
 
348
          *pix_ptr++ = get_data (pnm_file, bit_depth);
 
349
        else
 
350
          if (bit_depth <= 8)
 
351
            *pix_ptr++ = get_value (pnm_file, bit_depth);
 
352
          else
 
353
          {
 
354
            tmp16 = get_value (pnm_file, bit_depth);
 
355
            *pix_ptr = (png_byte) ((tmp16 >> 8) & 0xFF);
 
356
            pix_ptr++;
 
357
            *pix_ptr = (png_byte) (tmp16 & 0xFF);
 
358
            pix_ptr++;
 
359
          }
 
360
      }
 
361
 
 
362
      if (alpha) /* read alpha-channel from pgm file */
 
363
      {
 
364
        if (alpha_raw)
 
365
          *pix_ptr++ = get_data (alpha_file, alpha_depth);
 
366
        else
 
367
          if (alpha_depth <= 8)
 
368
            *pix_ptr++ = get_value (alpha_file, bit_depth);
 
369
          else
 
370
          {
 
371
            tmp16 = get_value (alpha_file, bit_depth);
 
372
            *pix_ptr++ = (png_byte) ((tmp16 >> 8) & 0xFF);
 
373
            *pix_ptr++ = (png_byte) (tmp16 & 0xFF);
 
374
          }
 
375
      } /* if alpha */
 
376
 
 
377
    } /* end for col */
 
378
  } /* end for row */
 
379
 
 
380
  /* prepare the standard PNG structures */
 
381
  png_ptr = png_create_write_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
 
382
  if (!png_ptr)
 
383
  {
 
384
    return FALSE;
 
385
  }
 
386
  info_ptr = png_create_info_struct (png_ptr);
 
387
  if (!info_ptr)
 
388
  {
 
389
    png_destroy_write_struct (&png_ptr, (png_infopp) NULL);
 
390
    return FALSE;
 
391
  }
 
392
 
 
393
  /* setjmp() must be called in every function that calls a PNG-reading libpng function */
 
394
  if (setjmp (png_jmpbuf(png_ptr)))
 
395
  {
 
396
    png_destroy_write_struct (&png_ptr, (png_infopp) NULL);
 
397
    return FALSE;
 
398
  }
 
399
 
 
400
  /* initialize the png structure */
 
401
  png_init_io (png_ptr, png_file);
 
402
 
 
403
  /* we're going to write more or less the same PNG as the input file */
 
404
  png_set_IHDR (png_ptr, info_ptr, width, height, bit_depth, color_type,
 
405
    (!interlace) ? PNG_INTERLACE_NONE : PNG_INTERLACE_ADAM7,
 
406
    PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
 
407
 
 
408
  /* write the file header information */
 
409
  png_write_info (png_ptr, info_ptr);
 
410
 
 
411
  /* if needed we will allocate memory for an new array of row-pointers */
 
412
  if (row_pointers == (unsigned char**) NULL)
 
413
  {
 
414
    if ((row_pointers = (png_byte **) malloc (height * sizeof (png_bytep))) == NULL)
 
415
    {
 
416
      png_destroy_write_struct (&png_ptr, (png_infopp) NULL);
 
417
      return FALSE;
 
418
    }
 
419
  }
 
420
 
 
421
  /* set the individual row_pointers to point at the correct offsets */
 
422
  for (i = 0; i < (height); i++)
 
423
    row_pointers[i] = png_pixels + i * row_bytes;
 
424
 
 
425
  /* write out the entire image data in one call */
 
426
  png_write_image (png_ptr, row_pointers);
 
427
 
 
428
  /* write the additional chuncks to the PNG file (not really needed) */
 
429
  png_write_end (png_ptr, info_ptr);
 
430
 
 
431
  /* clean up after the write, and free any memory allocated */
 
432
  png_destroy_write_struct (&png_ptr, (png_infopp) NULL);
 
433
 
 
434
  if (row_pointers != (unsigned char**) NULL)
 
435
    free (row_pointers);
 
436
  if (png_pixels != (unsigned char*) NULL)
 
437
    free (png_pixels);
 
438
 
 
439
  return TRUE;
 
440
} /* end of pnm2png */
 
441
 
 
442
/*
 
443
 * get_token() - gets the first string after whitespace
 
444
 */
 
445
 
 
446
void get_token(FILE *pnm_file, char *token)
 
447
{
 
448
  int i = 0;
 
449
 
 
450
  /* remove white-space */
 
451
  do
 
452
  {
 
453
    token[i] = (unsigned char) fgetc (pnm_file);
 
454
  }
 
455
  while ((token[i] == '\n') || (token[i] == '\r') || (token[i] == ' '));
 
456
 
 
457
  /* read string */
 
458
  do
 
459
  {
 
460
    i++;
 
461
    token[i] = (unsigned char) fgetc (pnm_file);
 
462
  }
 
463
  while ((token[i] != '\n') && (token[i] != '\r') && (token[i] != ' '));
 
464
 
 
465
  token[i] = '\0';
 
466
 
 
467
  return;
 
468
}
 
469
 
 
470
/*
 
471
 * get_data() - takes first byte and converts into next pixel value,
 
472
 *        taking as much bits as defined by bit-depth and
 
473
 *        using the bit-depth to fill up a byte (0Ah -> AAh)
 
474
 */
 
475
 
 
476
png_uint_32 get_data (FILE *pnm_file, int depth)
 
477
{
 
478
  static int bits_left = 0;
 
479
  static int old_value = 0;
 
480
  static int mask = 0;
 
481
  int i;
 
482
  png_uint_32 ret_value;
 
483
 
 
484
  if (mask == 0)
 
485
    for (i = 0; i < depth; i++)
 
486
      mask = (mask >> 1) | 0x80;
 
487
 
 
488
  if (bits_left <= 0)
 
489
  {
 
490
    old_value = fgetc (pnm_file);
 
491
    bits_left = 8;
 
492
  }
 
493
 
 
494
  ret_value = old_value & mask;
 
495
  for (i = 1; i < (8 / depth); i++)
 
496
    ret_value = ret_value || (ret_value >> depth);
 
497
 
 
498
  old_value = (old_value << depth) & 0xFF;
 
499
  bits_left -= depth;
 
500
 
 
501
  return ret_value;
 
502
}
 
503
 
 
504
/*
 
505
 * get_value() - takes first (numeric) string and converts into number,
 
506
 *         using the bit-depth to fill up a byte (0Ah -> AAh)
 
507
 */
 
508
 
 
509
png_uint_32 get_value (FILE *pnm_file, int depth)
 
510
{
 
511
  static png_uint_32 mask = 0;
 
512
  png_byte token[16];
 
513
  png_uint_32 ret_value;
 
514
  int i = 0;
 
515
 
 
516
  if (mask == 0)
 
517
    for (i = 0; i < depth; i++)
 
518
      mask = (mask << 1) | 0x01;
 
519
 
 
520
  get_token (pnm_file, (char *) token);
 
521
  sscanf ((const char *) token, "%lu", &ret_value);
 
522
 
 
523
  ret_value &= mask;
 
524
 
 
525
  if (depth < 8)
 
526
    for (i = 0; i < (8 / depth); i++)
 
527
      ret_value = (ret_value << depth) || ret_value;
 
528
 
 
529
  return ret_value;
 
530
}
 
531
 
 
532
/* end of source */
 
533