~baltix/+junk/irrlicht-test

« back to all changes in this revision

Viewing changes to source/Irrlicht/libpng/contrib/gregbook/writepng.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
 
 
3
   wpng - simple PNG-writing program                             writepng.c
 
4
 
 
5
  ---------------------------------------------------------------------------
 
6
 
 
7
      Copyright (c) 1998-2007 Greg Roelofs.  All rights reserved.
 
8
 
 
9
      This software is provided "as is," without warranty of any kind,
 
10
      express or implied.  In no event shall the author or contributors
 
11
      be held liable for any damages arising in any way from the use of
 
12
      this software.
 
13
 
 
14
      The contents of this file are DUAL-LICENSED.  You may modify and/or
 
15
      redistribute this software according to the terms of one of the
 
16
      following two licenses (at your option):
 
17
 
 
18
 
 
19
      LICENSE 1 ("BSD-like with advertising clause"):
 
20
 
 
21
      Permission is granted to anyone to use this software for any purpose,
 
22
      including commercial applications, and to alter it and redistribute
 
23
      it freely, subject to the following restrictions:
 
24
 
 
25
      1. Redistributions of source code must retain the above copyright
 
26
         notice, disclaimer, and this list of conditions.
 
27
      2. Redistributions in binary form must reproduce the above copyright
 
28
         notice, disclaimer, and this list of conditions in the documenta-
 
29
         tion and/or other materials provided with the distribution.
 
30
      3. All advertising materials mentioning features or use of this
 
31
         software must display the following acknowledgment:
 
32
 
 
33
            This product includes software developed by Greg Roelofs
 
34
            and contributors for the book, "PNG: The Definitive Guide,"
 
35
            published by O'Reilly and Associates.
 
36
 
 
37
 
 
38
      LICENSE 2 (GNU GPL v2 or later):
 
39
 
 
40
      This program is free software; you can redistribute it and/or modify
 
41
      it under the terms of the GNU General Public License as published by
 
42
      the Free Software Foundation; either version 2 of the License, or
 
43
      (at your option) any later version.
 
44
 
 
45
      This program is distributed in the hope that it will be useful,
 
46
      but WITHOUT ANY WARRANTY; without even the implied warranty of
 
47
      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
48
      GNU General Public License for more details.
 
49
 
 
50
      You should have received a copy of the GNU General Public License
 
51
      along with this program; if not, write to the Free Software Foundation,
 
52
      Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
53
 
 
54
  ---------------------------------------------------------------------------*/
 
55
 
 
56
 
 
57
#include <stdlib.h>     /* for exit() prototype */
 
58
 
 
59
#include "png.h"        /* libpng header; includes zlib.h and setjmp.h */
 
60
#include "writepng.h"   /* typedefs, common macros, public prototypes */
 
61
 
 
62
 
 
63
/* local prototype */
 
64
 
 
65
static void writepng_error_handler(png_structp png_ptr, png_const_charp msg);
 
66
 
 
67
 
 
68
 
 
69
void writepng_version_info(void)
 
70
{
 
71
  fprintf(stderr, "   Compiled with libpng %s; using libpng %s.\n",
 
72
    PNG_LIBPNG_VER_STRING, png_libpng_ver);
 
73
  fprintf(stderr, "   Compiled with zlib %s; using zlib %s.\n",
 
74
    ZLIB_VERSION, zlib_version);
 
75
}
 
76
 
 
77
 
 
78
 
 
79
 
 
80
/* returns 0 for success, 2 for libpng problem, 4 for out of memory, 11 for
 
81
 *  unexpected pnmtype; note that outfile might be stdout */
 
82
 
 
83
int writepng_init(mainprog_info *mainprog_ptr)
 
84
{
 
85
    png_structp  png_ptr;       /* note:  temporary variables! */
 
86
    png_infop  info_ptr;
 
87
    int color_type, interlace_type;
 
88
 
 
89
 
 
90
    /* could also replace libpng warning-handler (final NULL), but no need: */
 
91
 
 
92
    png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, mainprog_ptr,
 
93
      writepng_error_handler, NULL);
 
94
    if (!png_ptr)
 
95
        return 4;   /* out of memory */
 
96
 
 
97
    info_ptr = png_create_info_struct(png_ptr);
 
98
    if (!info_ptr) {
 
99
        png_destroy_write_struct(&png_ptr, NULL);
 
100
        return 4;   /* out of memory */
 
101
    }
 
102
 
 
103
 
 
104
    /* setjmp() must be called in every function that calls a PNG-writing
 
105
     * libpng function, unless an alternate error handler was installed--
 
106
     * but compatible error handlers must either use longjmp() themselves
 
107
     * (as in this program) or exit immediately, so here we go: */
 
108
 
 
109
    if (setjmp(mainprog_ptr->jmpbuf)) {
 
110
        png_destroy_write_struct(&png_ptr, &info_ptr);
 
111
        return 2;
 
112
    }
 
113
 
 
114
 
 
115
    /* make sure outfile is (re)opened in BINARY mode */
 
116
 
 
117
    png_init_io(png_ptr, mainprog_ptr->outfile);
 
118
 
 
119
 
 
120
    /* set the compression levels--in general, always want to leave filtering
 
121
     * turned on (except for palette images) and allow all of the filters,
 
122
     * which is the default; want 32K zlib window, unless entire image buffer
 
123
     * is 16K or smaller (unknown here)--also the default; usually want max
 
124
     * compression (NOT the default); and remaining compression flags should
 
125
     * be left alone */
 
126
 
 
127
    png_set_compression_level(png_ptr, Z_BEST_COMPRESSION);
 
128
/*
 
129
    >> this is default for no filtering; Z_FILTERED is default otherwise:
 
130
    png_set_compression_strategy(png_ptr, Z_DEFAULT_STRATEGY);
 
131
    >> these are all defaults:
 
132
    png_set_compression_mem_level(png_ptr, 8);
 
133
    png_set_compression_window_bits(png_ptr, 15);
 
134
    png_set_compression_method(png_ptr, 8);
 
135
 */
 
136
 
 
137
 
 
138
    /* set the image parameters appropriately */
 
139
 
 
140
    if (mainprog_ptr->pnmtype == 5)
 
141
        color_type = PNG_COLOR_TYPE_GRAY;
 
142
    else if (mainprog_ptr->pnmtype == 6)
 
143
        color_type = PNG_COLOR_TYPE_RGB;
 
144
    else if (mainprog_ptr->pnmtype == 8)
 
145
        color_type = PNG_COLOR_TYPE_RGB_ALPHA;
 
146
    else {
 
147
        png_destroy_write_struct(&png_ptr, &info_ptr);
 
148
        return 11;
 
149
    }
 
150
 
 
151
    interlace_type = mainprog_ptr->interlaced? PNG_INTERLACE_ADAM7 :
 
152
                                               PNG_INTERLACE_NONE;
 
153
 
 
154
    png_set_IHDR(png_ptr, info_ptr, mainprog_ptr->width, mainprog_ptr->height,
 
155
      mainprog_ptr->sample_depth, color_type, interlace_type,
 
156
      PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
 
157
 
 
158
    if (mainprog_ptr->gamma > 0.0)
 
159
        png_set_gAMA(png_ptr, info_ptr, mainprog_ptr->gamma);
 
160
 
 
161
    if (mainprog_ptr->have_bg) {   /* we know it's RGBA, not gray+alpha */
 
162
        png_color_16  background;
 
163
 
 
164
        background.red = mainprog_ptr->bg_red;
 
165
        background.green = mainprog_ptr->bg_green;
 
166
        background.blue = mainprog_ptr->bg_blue;
 
167
        png_set_bKGD(png_ptr, info_ptr, &background);
 
168
    }
 
169
 
 
170
    if (mainprog_ptr->have_time) {
 
171
        png_time  modtime;
 
172
 
 
173
        png_convert_from_time_t(&modtime, mainprog_ptr->modtime);
 
174
        png_set_tIME(png_ptr, info_ptr, &modtime);
 
175
    }
 
176
 
 
177
    if (mainprog_ptr->have_text) {
 
178
        png_text  text[6];
 
179
        int  num_text = 0;
 
180
 
 
181
        if (mainprog_ptr->have_text & TEXT_TITLE) {
 
182
            text[num_text].compression = PNG_TEXT_COMPRESSION_NONE;
 
183
            text[num_text].key = "Title";
 
184
            text[num_text].text = mainprog_ptr->title;
 
185
            ++num_text;
 
186
        }
 
187
        if (mainprog_ptr->have_text & TEXT_AUTHOR) {
 
188
            text[num_text].compression = PNG_TEXT_COMPRESSION_NONE;
 
189
            text[num_text].key = "Author";
 
190
            text[num_text].text = mainprog_ptr->author;
 
191
            ++num_text;
 
192
        }
 
193
        if (mainprog_ptr->have_text & TEXT_DESC) {
 
194
            text[num_text].compression = PNG_TEXT_COMPRESSION_NONE;
 
195
            text[num_text].key = "Description";
 
196
            text[num_text].text = mainprog_ptr->desc;
 
197
            ++num_text;
 
198
        }
 
199
        if (mainprog_ptr->have_text & TEXT_COPY) {
 
200
            text[num_text].compression = PNG_TEXT_COMPRESSION_NONE;
 
201
            text[num_text].key = "Copyright";
 
202
            text[num_text].text = mainprog_ptr->copyright;
 
203
            ++num_text;
 
204
        }
 
205
        if (mainprog_ptr->have_text & TEXT_EMAIL) {
 
206
            text[num_text].compression = PNG_TEXT_COMPRESSION_NONE;
 
207
            text[num_text].key = "E-mail";
 
208
            text[num_text].text = mainprog_ptr->email;
 
209
            ++num_text;
 
210
        }
 
211
        if (mainprog_ptr->have_text & TEXT_URL) {
 
212
            text[num_text].compression = PNG_TEXT_COMPRESSION_NONE;
 
213
            text[num_text].key = "URL";
 
214
            text[num_text].text = mainprog_ptr->url;
 
215
            ++num_text;
 
216
        }
 
217
        png_set_text(png_ptr, info_ptr, text, num_text);
 
218
    }
 
219
 
 
220
 
 
221
    /* write all chunks up to (but not including) first IDAT */
 
222
 
 
223
    png_write_info(png_ptr, info_ptr);
 
224
 
 
225
 
 
226
    /* if we wanted to write any more text info *after* the image data, we
 
227
     * would set up text struct(s) here and call png_set_text() again, with
 
228
     * just the new data; png_set_tIME() could also go here, but it would
 
229
     * have no effect since we already called it above (only one tIME chunk
 
230
     * allowed) */
 
231
 
 
232
 
 
233
    /* set up the transformations:  for now, just pack low-bit-depth pixels
 
234
     * into bytes (one, two or four pixels per byte) */
 
235
 
 
236
    png_set_packing(png_ptr);
 
237
/*  png_set_shift(png_ptr, &sig_bit);  to scale low-bit-depth values */
 
238
 
 
239
 
 
240
    /* make sure we save our pointers for use in writepng_encode_image() */
 
241
 
 
242
    mainprog_ptr->png_ptr = png_ptr;
 
243
    mainprog_ptr->info_ptr = info_ptr;
 
244
 
 
245
 
 
246
    /* OK, that's all we need to do for now; return happy */
 
247
 
 
248
    return 0;
 
249
}
 
250
 
 
251
 
 
252
 
 
253
 
 
254
 
 
255
/* returns 0 for success, 2 for libpng (longjmp) problem */
 
256
 
 
257
int writepng_encode_image(mainprog_info *mainprog_ptr)
 
258
{
 
259
    png_structp png_ptr = (png_structp)mainprog_ptr->png_ptr;
 
260
    png_infop info_ptr = (png_infop)mainprog_ptr->info_ptr;
 
261
 
 
262
 
 
263
    /* as always, setjmp() must be called in every function that calls a
 
264
     * PNG-writing libpng function */
 
265
 
 
266
    if (setjmp(mainprog_ptr->jmpbuf)) {
 
267
        png_destroy_write_struct(&png_ptr, &info_ptr);
 
268
        mainprog_ptr->png_ptr = NULL;
 
269
        mainprog_ptr->info_ptr = NULL;
 
270
        return 2;
 
271
    }
 
272
 
 
273
 
 
274
    /* and now we just write the whole image; libpng takes care of interlacing
 
275
     * for us */
 
276
 
 
277
    png_write_image(png_ptr, mainprog_ptr->row_pointers);
 
278
 
 
279
 
 
280
    /* since that's it, we also close out the end of the PNG file now--if we
 
281
     * had any text or time info to write after the IDATs, second argument
 
282
     * would be info_ptr, but we optimize slightly by sending NULL pointer: */
 
283
 
 
284
    png_write_end(png_ptr, NULL);
 
285
 
 
286
    return 0;
 
287
}
 
288
 
 
289
 
 
290
 
 
291
 
 
292
 
 
293
/* returns 0 if succeeds, 2 if libpng problem */
 
294
 
 
295
int writepng_encode_row(mainprog_info *mainprog_ptr)  /* NON-interlaced only! */
 
296
{
 
297
    png_structp png_ptr = (png_structp)mainprog_ptr->png_ptr;
 
298
    png_infop info_ptr = (png_infop)mainprog_ptr->info_ptr;
 
299
 
 
300
 
 
301
    /* as always, setjmp() must be called in every function that calls a
 
302
     * PNG-writing libpng function */
 
303
 
 
304
    if (setjmp(mainprog_ptr->jmpbuf)) {
 
305
        png_destroy_write_struct(&png_ptr, &info_ptr);
 
306
        mainprog_ptr->png_ptr = NULL;
 
307
        mainprog_ptr->info_ptr = NULL;
 
308
        return 2;
 
309
    }
 
310
 
 
311
 
 
312
    /* image_data points at our one row of image data */
 
313
 
 
314
    png_write_row(png_ptr, mainprog_ptr->image_data);
 
315
 
 
316
    return 0;
 
317
}
 
318
 
 
319
 
 
320
 
 
321
 
 
322
 
 
323
/* returns 0 if succeeds, 2 if libpng problem */
 
324
 
 
325
int writepng_encode_finish(mainprog_info *mainprog_ptr)   /* NON-interlaced! */
 
326
{
 
327
    png_structp png_ptr = (png_structp)mainprog_ptr->png_ptr;
 
328
    png_infop info_ptr = (png_infop)mainprog_ptr->info_ptr;
 
329
 
 
330
 
 
331
    /* as always, setjmp() must be called in every function that calls a
 
332
     * PNG-writing libpng function */
 
333
 
 
334
    if (setjmp(mainprog_ptr->jmpbuf)) {
 
335
        png_destroy_write_struct(&png_ptr, &info_ptr);
 
336
        mainprog_ptr->png_ptr = NULL;
 
337
        mainprog_ptr->info_ptr = NULL;
 
338
        return 2;
 
339
    }
 
340
 
 
341
 
 
342
    /* close out PNG file; if we had any text or time info to write after
 
343
     * the IDATs, second argument would be info_ptr: */
 
344
 
 
345
    png_write_end(png_ptr, NULL);
 
346
 
 
347
    return 0;
 
348
}
 
349
 
 
350
 
 
351
 
 
352
 
 
353
 
 
354
void writepng_cleanup(mainprog_info *mainprog_ptr)
 
355
{
 
356
    png_structp png_ptr = (png_structp)mainprog_ptr->png_ptr;
 
357
    png_infop info_ptr = (png_infop)mainprog_ptr->info_ptr;
 
358
 
 
359
    if (png_ptr && info_ptr)
 
360
        png_destroy_write_struct(&png_ptr, &info_ptr);
 
361
}
 
362
 
 
363
 
 
364
 
 
365
 
 
366
 
 
367
static void writepng_error_handler(png_structp png_ptr, png_const_charp msg)
 
368
{
 
369
    mainprog_info  *mainprog_ptr;
 
370
 
 
371
    /* This function, aside from the extra step of retrieving the "error
 
372
     * pointer" (below) and the fact that it exists within the application
 
373
     * rather than within libpng, is essentially identical to libpng's
 
374
     * default error handler.  The second point is critical:  since both
 
375
     * setjmp() and longjmp() are called from the same code, they are
 
376
     * guaranteed to have compatible notions of how big a jmp_buf is,
 
377
     * regardless of whether _BSD_SOURCE or anything else has (or has not)
 
378
     * been defined. */
 
379
 
 
380
    fprintf(stderr, "writepng libpng error: %s\n", msg);
 
381
    fflush(stderr);
 
382
 
 
383
    mainprog_ptr = png_get_error_ptr(png_ptr);
 
384
    if (mainprog_ptr == NULL) {         /* we are completely hosed now */
 
385
        fprintf(stderr,
 
386
          "writepng severe error:  jmpbuf not recoverable; terminating.\n");
 
387
        fflush(stderr);
 
388
        exit(99);
 
389
    }
 
390
 
 
391
    longjmp(mainprog_ptr->jmpbuf, 1);
 
392
}