Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4349 Serge 1
 
2
 *
3
 * Last changed in libpng 1.6.1 [March 28, 2013]
4
 * Copyright (c) 1998-2013 Glenn Randers-Pehrson
5
 * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
6
 * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
7
 *
8
 * This code is released under the libpng license.
9
 * For conditions of distribution and use, see the disclaimer
10
 * and license in png.h
11
 *
12
 * This file provides a location for all error handling.  Users who
13
 * need special error handling are expected to write replacement functions
14
 * and use png_set_error_fn() to use those functions.  See the instructions
15
 * at each function.
16
 */
17
18
 
19
20
 
21
22
 
23
    png_const_charp error_message)),PNG_NORETURN);
24
25
 
26
static void /* PRIVATE */
27
png_default_warning PNGARG((png_const_structrp png_ptr,
28
   png_const_charp warning_message));
29
#endif /* PNG_WARNINGS_SUPPORTED */
30
31
 
32
 * should not be changed.  If there is a need to handle errors differently,
33
 * you should supply a replacement error function and use png_set_error_fn()
34
 * to replace the error function at run-time.
35
 */
36
#ifdef PNG_ERROR_TEXT_SUPPORTED
37
PNG_FUNCTION(void,PNGAPI
38
png_error,(png_const_structrp png_ptr, png_const_charp error_message),
39
   PNG_NORETURN)
40
{
41
#ifdef PNG_ERROR_NUMBERS_SUPPORTED
42
   char msg[16];
43
   if (png_ptr != NULL)
44
   {
45
      if (png_ptr->flags&
46
         (PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT))
47
      {
48
         if (*error_message == PNG_LITERAL_SHARP)
49
         {
50
            /* Strip "#nnnn " from beginning of error message. */
51
            int offset;
52
            for (offset = 1; offset<15; offset++)
53
               if (error_message[offset] == ' ')
54
                  break;
55
56
 
57
            {
58
               int i;
59
               for (i = 0; i < offset - 1; i++)
60
                  msg[i] = error_message[i + 1];
61
               msg[i - 1] = '\0';
62
               error_message = msg;
63
            }
64
65
 
66
               error_message += offset;
67
      }
68
69
 
70
      {
71
         if (png_ptr->flags&PNG_FLAG_STRIP_ERROR_TEXT)
72
         {
73
            msg[0] = '0';
74
            msg[1] = '\0';
75
            error_message = msg;
76
         }
77
       }
78
     }
79
   }
80
#endif
81
   if (png_ptr != NULL && png_ptr->error_fn != NULL)
82
      (*(png_ptr->error_fn))(png_constcast(png_structrp,png_ptr),
83
          error_message);
84
85
 
86
      use the default handler, which will not return. */
87
   png_default_error(png_ptr, error_message);
88
}
89
#else
90
PNG_FUNCTION(void,PNGAPI
91
png_err,(png_const_structrp png_ptr),PNG_NORETURN)
92
{
93
   /* Prior to 1.5.2 the error_fn received a NULL pointer, expressed
94
    * erroneously as '\0', instead of the empty string "".  This was
95
    * apparently an error, introduced in libpng-1.2.20, and png_default_error
96
    * will crash in this case.
97
    */
98
   if (png_ptr != NULL && png_ptr->error_fn != NULL)
99
      (*(png_ptr->error_fn))(png_constcast(png_structrp,png_ptr), "");
100
101
 
102
      use the default handler, which will not return. */
103
   png_default_error(png_ptr, "");
104
}
105
#endif /* PNG_ERROR_TEXT_SUPPORTED */
106
107
 
108
 * error checking is not required in the caller.
109
 */
110
size_t
111
png_safecat(png_charp buffer, size_t bufsize, size_t pos,
112
   png_const_charp string)
113
{
114
   if (buffer != NULL && pos < bufsize)
115
   {
116
      if (string != NULL)
117
         while (*string != '\0' && pos < bufsize-1)
118
           buffer[pos++] = *string++;
119
120
 
121
   }
122
123
 
124
}
125
126
 
127
/* Utility to dump an unsigned value into a buffer, given a start pointer and
128
 * and end pointer (which should point just *beyond* the end of the buffer!)
129
 * Returns the pointer to the start of the formatted string.
130
 */
131
png_charp
132
png_format_number(png_const_charp start, png_charp end, int format,
133
   png_alloc_size_t number)
134
{
135
   int count = 0;    /* number of digits output */
136
   int mincount = 1; /* minimum number required */
137
   int output = 0;   /* digit output (for the fixed point format) */
138
139
 
140
141
 
142
    * number zero.
143
    */
144
   while (end > start && (number != 0 || count < mincount))
145
   {
146
147
 
148
149
 
150
      {
151
         case PNG_NUMBER_FORMAT_fixed:
152
            /* Needs five digits (the fraction) */
153
            mincount = 5;
154
            if (output || number % 10 != 0)
155
            {
156
               *--end = digits[number % 10];
157
               output = 1;
158
            }
159
            number /= 10;
160
            break;
161
162
 
163
            /* Expects at least 2 digits. */
164
            mincount = 2;
165
            /* FALL THROUGH */
166
167
 
168
            *--end = digits[number % 10];
169
            number /= 10;
170
            break;
171
172
 
173
            /* This format expects at least two digits */
174
            mincount = 2;
175
            /* FALL THROUGH */
176
177
 
178
            *--end = digits[number & 0xf];
179
            number >>= 4;
180
            break;
181
182
 
183
            number = 0;
184
            break;
185
      }
186
187
 
188
      ++count;
189
190
 
191
      if (format == PNG_NUMBER_FORMAT_fixed) if (count == 5) if (end > start)
192
      {
193
         /* End of the fraction, but maybe nothing was output?  In that case
194
          * drop the decimal point.  If the number is a true zero handle that
195
          * here.
196
          */
197
         if (output)
198
            *--end = '.';
199
         else if (number == 0) /* and !output */
200
            *--end = '0';
201
      }
202
   }
203
204
 
205
}
206
#endif
207
208
 
209
/* This function is called whenever there is a non-fatal error.  This function
210
 * should not be changed.  If there is a need to handle warnings differently,
211
 * you should supply a replacement warning function and use
212
 * png_set_error_fn() to replace the warning function at run-time.
213
 */
214
void PNGAPI
215
png_warning(png_const_structrp png_ptr, png_const_charp warning_message)
216
{
217
   int offset = 0;
218
   if (png_ptr != NULL)
219
   {
220
#ifdef PNG_ERROR_NUMBERS_SUPPORTED
221
   if (png_ptr->flags&
222
       (PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT))
223
#endif
224
      {
225
         if (*warning_message == PNG_LITERAL_SHARP)
226
         {
227
            for (offset = 1; offset < 15; offset++)
228
               if (warning_message[offset] == ' ')
229
                  break;
230
         }
231
      }
232
   }
233
   if (png_ptr != NULL && png_ptr->warning_fn != NULL)
234
      (*(png_ptr->warning_fn))(png_constcast(png_structrp,png_ptr),
235
         warning_message + offset);
236
   else
237
      png_default_warning(png_ptr, warning_message + offset);
238
}
239
240
 
241
 * PNG_WARNING_PARAMETER_COUNT parameters.  In the format string the parameter
242
 * is introduced by @, where 'number' starts at 1.  This follows the
243
 * standard established by X/Open for internationalizable error messages.
244
 */
245
void
246
png_warning_parameter(png_warning_parameters p, int number,
247
   png_const_charp string)
248
{
249
   if (number > 0 && number <= PNG_WARNING_PARAMETER_COUNT)
250
      (void)png_safecat(p[number-1], (sizeof p[number-1]), 0, string);
251
}
252
253
 
254
png_warning_parameter_unsigned(png_warning_parameters p, int number, int format,
255
   png_alloc_size_t value)
256
{
257
   char buffer[PNG_NUMBER_BUFFER_SIZE];
258
   png_warning_parameter(p, number, PNG_FORMAT_NUMBER(buffer, format, value));
259
}
260
261
 
262
png_warning_parameter_signed(png_warning_parameters p, int number, int format,
263
   png_int_32 value)
264
{
265
   png_alloc_size_t u;
266
   png_charp str;
267
   char buffer[PNG_NUMBER_BUFFER_SIZE];
268
269
 
270
   u = (png_alloc_size_t)value;
271
   if (value < 0)
272
      u = ~u + 1;
273
274
 
275
276
 
277
      *--str = '-';
278
279
 
280
}
281
282
 
283
png_formatted_warning(png_const_structrp png_ptr, png_warning_parameters p,
284
   png_const_charp message)
285
{
286
   /* The internal buffer is just 192 bytes - enough for all our messages,
287
    * overflow doesn't happen because this code checks!  If someone figures
288
    * out how to send us a message longer than 192 bytes, all that will
289
    * happen is that the message will be truncated appropriately.
290
    */
291
   size_t i = 0; /* Index in the msg[] buffer: */
292
   char msg[192];
293
294
 
295
    * to msg[i++] then returns here to validate that there is still space for
296
    * the trailing '\0'.  It may (in the case of a parameter) read more than
297
    * one character from message[]; it must check for '\0' and continue to the
298
    * test if it finds the end of string.
299
    */
300
   while (i<(sizeof msg)-1 && *message != '\0')
301
   {
302
      /* '@' at end of string is now just printed (previously it was skipped);
303
       * it is an error in the calling code to terminate the string with @.
304
       */
305
      if (p != NULL && *message == '@' && message[1] != '\0')
306
      {
307
         int parameter_char = *++message; /* Consume the '@' */
308
         static const char valid_parameters[] = "123456789";
309
         int parameter = 0;
310
311
 
312
          * parameter to use.
313
          */
314
         while (valid_parameters[parameter] != parameter_char &&
315
            valid_parameters[parameter] != '\0')
316
            ++parameter;
317
318
 
319
         if (parameter < PNG_WARNING_PARAMETER_COUNT)
320
         {
321
            /* Append this parameter */
322
            png_const_charp parm = p[parameter];
323
            png_const_charp pend = p[parameter] + (sizeof p[parameter]);
324
325
 
326
             * that parm[] has been initialized, so there is no guarantee of a
327
             * trailing '\0':
328
             */
329
            while (i<(sizeof msg)-1 && *parm != '\0' && parm < pend)
330
               msg[i++] = *parm++;
331
332
 
333
            ++message;
334
            continue;
335
         }
336
337
 
338
          * copy that.  This is known not to be '\0' because of the test above.
339
          */
340
      }
341
342
 
343
       * above where there is a lone '@' at the end of the message string.
344
       */
345
      msg[i++] = *message++;
346
   }
347
348
 
349
   msg[i] = '\0';
350
351
 
352
    * PNG_MAX_ERROR_TEXT, but that is only used for 'chunk' errors and these
353
    * are not (currently) formatted.
354
    */
355
   png_warning(png_ptr, msg);
356
}
357
#endif /* PNG_WARNINGS_SUPPORTED */
358
359
 
360
void PNGAPI
361
png_benign_error(png_const_structrp png_ptr, png_const_charp error_message)
362
{
363
   if (png_ptr->flags & PNG_FLAG_BENIGN_ERRORS_WARN)
364
   {
365
#     ifdef PNG_READ_SUPPORTED
366
         if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0 &&
367
            png_ptr->chunk_name != 0)
368
            png_chunk_warning(png_ptr, error_message);
369
         else
370
#     endif
371
      png_warning(png_ptr, error_message);
372
   }
373
374
 
375
   {
376
#     ifdef PNG_READ_SUPPORTED
377
         if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0 &&
378
            png_ptr->chunk_name != 0)
379
            png_chunk_error(png_ptr, error_message);
380
         else
381
#     endif
382
      png_error(png_ptr, error_message);
383
   }
384
}
385
386
 
387
png_app_warning(png_const_structrp png_ptr, png_const_charp error_message)
388
{
389
  if (png_ptr->flags & PNG_FLAG_APP_WARNINGS_WARN)
390
     png_warning(png_ptr, error_message);
391
  else
392
     png_error(png_ptr, error_message);
393
}
394
395
 
396
png_app_error(png_const_structrp png_ptr, png_const_charp error_message)
397
{
398
  if (png_ptr->flags & PNG_FLAG_APP_ERRORS_WARN)
399
     png_warning(png_ptr, error_message);
400
  else
401
     png_error(png_ptr, error_message);
402
}
403
#endif /* BENIGN_ERRORS */
404
405
 
406
 * to the current chunk.  The chunk name comes from png_ptr->chunk_name,
407
 * this is used to prefix the message.  The message is limited in length
408
 * to 63 bytes, the name characters are output as hex digits wrapped in []
409
 * if the character is invalid.
410
 */
411
#define isnonalpha(c) ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97))
412
static PNG_CONST char png_digit[16] = {
413
   '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
414
   'A', 'B', 'C', 'D', 'E', 'F'
415
};
416
417
 
418
#if defined(PNG_WARNINGS_SUPPORTED) || defined(PNG_ERROR_TEXT_SUPPORTED)
419
static void /* PRIVATE */
420
png_format_buffer(png_const_structrp png_ptr, png_charp buffer, png_const_charp
421
    error_message)
422
{
423
   png_uint_32 chunk_name = png_ptr->chunk_name;
424
   int iout = 0, ishift = 24;
425
426
 
427
   {
428
      int c = (int)(chunk_name >> ishift) & 0xff;
429
430
 
431
      if (isnonalpha(c))
432
      {
433
         buffer[iout++] = PNG_LITERAL_LEFT_SQUARE_BRACKET;
434
         buffer[iout++] = png_digit[(c & 0xf0) >> 4];
435
         buffer[iout++] = png_digit[c & 0x0f];
436
         buffer[iout++] = PNG_LITERAL_RIGHT_SQUARE_BRACKET;
437
      }
438
439
 
440
      {
441
         buffer[iout++] = (char)c;
442
      }
443
   }
444
445
 
446
      buffer[iout] = '\0';
447
448
 
449
   {
450
      int iin = 0;
451
452
 
453
      buffer[iout++] = ' ';
454
455
 
456
         buffer[iout++] = error_message[iin++];
457
458
 
459
      buffer[iout] = '\0';
460
   }
461
}
462
#endif /* PNG_WARNINGS_SUPPORTED || PNG_ERROR_TEXT_SUPPORTED */
463
464
 
465
PNG_FUNCTION(void,PNGAPI
466
png_chunk_error,(png_const_structrp png_ptr, png_const_charp error_message),
467
   PNG_NORETURN)
468
{
469
   char msg[18+PNG_MAX_ERROR_TEXT];
470
   if (png_ptr == NULL)
471
      png_error(png_ptr, error_message);
472
473
 
474
   {
475
      png_format_buffer(png_ptr, msg, error_message);
476
      png_error(png_ptr, msg);
477
   }
478
}
479
#endif /* PNG_READ_SUPPORTED && PNG_ERROR_TEXT_SUPPORTED */
480
481
 
482
void PNGAPI
483
png_chunk_warning(png_const_structrp png_ptr, png_const_charp warning_message)
484
{
485
   char msg[18+PNG_MAX_ERROR_TEXT];
486
   if (png_ptr == NULL)
487
      png_warning(png_ptr, warning_message);
488
489
 
490
   {
491
      png_format_buffer(png_ptr, msg, warning_message);
492
      png_warning(png_ptr, msg);
493
   }
494
}
495
#endif /* PNG_WARNINGS_SUPPORTED */
496
497
 
498
#ifdef PNG_BENIGN_ERRORS_SUPPORTED
499
void PNGAPI
500
png_chunk_benign_error(png_const_structrp png_ptr, png_const_charp
501
    error_message)
502
{
503
   if (png_ptr->flags & PNG_FLAG_BENIGN_ERRORS_WARN)
504
      png_chunk_warning(png_ptr, error_message);
505
506
 
507
      png_chunk_error(png_ptr, error_message);
508
}
509
#endif
510
#endif /* PNG_READ_SUPPORTED */
511
512
 
513
png_chunk_report(png_const_structrp png_ptr, png_const_charp message, int error)
514
{
515
   /* This is always supported, but for just read or just write it
516
    * unconditionally does the right thing.
517
    */
518
#  if defined(PNG_READ_SUPPORTED) && defined(PNG_WRITE_SUPPORTED)
519
      if (png_ptr->mode & PNG_IS_READ_STRUCT)
520
#  endif
521
522
 
523
      {
524
         if (error < PNG_CHUNK_ERROR)
525
            png_chunk_warning(png_ptr, message);
526
527
 
528
            png_chunk_benign_error(png_ptr, message);
529
      }
530
#  endif
531
532
 
533
      else if (!(png_ptr->mode & PNG_IS_READ_STRUCT))
534
#  endif
535
536
 
537
      {
538
         if (error < PNG_CHUNK_WRITE_ERROR)
539
            png_app_warning(png_ptr, message);
540
541
 
542
            png_app_error(png_ptr, message);
543
      }
544
#  endif
545
}
546
547
 
548
#ifdef PNG_FLOATING_POINT_SUPPORTED
549
PNG_FUNCTION(void,
550
png_fixed_error,(png_const_structrp png_ptr, png_const_charp name),PNG_NORETURN)
551
{
552
#  define fixed_message "fixed point overflow in "
553
#  define fixed_message_ln ((sizeof fixed_message)-1)
554
   int  iin;
555
   char msg[fixed_message_ln+PNG_MAX_ERROR_TEXT];
556
   memcpy(msg, fixed_message, fixed_message_ln);
557
   iin = 0;
558
   if (name != NULL) while (iin < (PNG_MAX_ERROR_TEXT-1) && name[iin] != 0)
559
   {
560
      msg[fixed_message_ln + iin] = name[iin];
561
      ++iin;
562
   }
563
   msg[fixed_message_ln + iin] = 0;
564
   png_error(png_ptr, msg);
565
}
566
#endif
567
#endif
568
569
 
570
/* This API only exists if ANSI-C style error handling is used,
571
 * otherwise it is necessary for png_default_error to be overridden.
572
 */
573
jmp_buf* PNGAPI
574
png_set_longjmp_fn(png_structrp png_ptr, png_longjmp_ptr longjmp_fn,
575
    size_t jmp_buf_size)
576
{
577
   /* From libpng 1.6.0 the app gets one chance to set a 'jmpbuf_size' value
578
    * and it must not change after that.  Libpng doesn't care how big the
579
    * buffer is, just that it doesn't change.
580
    *
581
    * If the buffer size is no *larger* than the size of jmp_buf when libpng is
582
    * compiled a built in jmp_buf is returned; this preserves the pre-1.6.0
583
    * semantics that this call will not fail.  If the size is larger, however,
584
    * the buffer is allocated and this may fail, causing the function to return
585
    * NULL.
586
    */
587
   if (png_ptr == NULL)
588
      return NULL;
589
590
 
591
   {
592
      png_ptr->jmp_buf_size = 0; /* not allocated */
593
594
 
595
         png_ptr->jmp_buf_ptr = &png_ptr->jmp_buf_local;
596
597
 
598
      {
599
         png_ptr->jmp_buf_ptr = png_voidcast(jmp_buf *,
600
            png_malloc_warn(png_ptr, jmp_buf_size));
601
602
 
603
            return NULL; /* new NULL return on OOM */
604
605
 
606
      }
607
   }
608
609
 
610
   {
611
      size_t size = png_ptr->jmp_buf_size;
612
613
 
614
      {
615
         size = (sizeof png_ptr->jmp_buf_local);
616
         if (png_ptr->jmp_buf_ptr != &png_ptr->jmp_buf_local)
617
         {
618
            /* This is an internal error in libpng: somehow we have been left
619
             * with a stack allocated jmp_buf when the application regained
620
             * control.  It's always possible to fix this up, but for the moment
621
             * this is a png_error because that makes it easy to detect.
622
             */
623
            png_error(png_ptr, "Libpng jmp_buf still allocated");
624
            /* png_ptr->jmp_buf_ptr = &png_ptr->jmp_buf_local; */
625
         }
626
      }
627
628
 
629
      {
630
         png_warning(png_ptr, "Application jmp_buf size changed");
631
         return NULL; /* caller will probably crash: no choice here */
632
      }
633
   }
634
635
 
636
    * valid to change the function on every call.
637
    */
638
   png_ptr->longjmp_fn = longjmp_fn;
639
   return png_ptr->jmp_buf_ptr;
640
}
641
642
 
643
png_free_jmpbuf(png_structrp png_ptr)
644
{
645
   if (png_ptr != NULL)
646
   {
647
      jmp_buf *jb = png_ptr->jmp_buf_ptr;
648
649
 
650
       * pointer; used here and in png.c
651
       */
652
      if (jb != NULL && png_ptr->jmp_buf_size > 0)
653
      {
654
655
 
656
          * does not leave libpng in a state with no valid error handling: the
657
          * free always succeeds, if there is an error it gets ignored.
658
          */
659
         if (jb != &png_ptr->jmp_buf_local)
660
         {
661
            /* Make an internal, libpng, jmp_buf to return here */
662
            jmp_buf free_jmp_buf;
663
664
 
665
            {
666
               png_ptr->jmp_buf_ptr = &free_jmp_buf; /* come back here */
667
               png_ptr->jmp_buf_size = 0; /* stack allocation */
668
               png_ptr->longjmp_fn = longjmp;
669
               png_free(png_ptr, jb); /* Return to setjmp on error */
670
            }
671
         }
672
      }
673
674
 
675
      png_ptr->jmp_buf_size = 0;
676
      png_ptr->jmp_buf_ptr = NULL;
677
      png_ptr->longjmp_fn = 0;
678
   }
679
}
680
#endif
681
682
 
683
 * this function MUST NOT RETURN, or the program will likely crash.  This
684
 * function is used by default, or if the program supplies NULL for the
685
 * error function pointer in png_set_error_fn().
686
 */
687
static PNG_FUNCTION(void /* PRIVATE */,
688
png_default_error,(png_const_structrp png_ptr, png_const_charp error_message),
689
   PNG_NORETURN)
690
{
691
#ifdef PNG_CONSOLE_IO_SUPPORTED
692
#ifdef PNG_ERROR_NUMBERS_SUPPORTED
693
   /* Check on NULL only added in 1.5.4 */
694
   if (error_message != NULL && *error_message == PNG_LITERAL_SHARP)
695
   {
696
      /* Strip "#nnnn " from beginning of error message. */
697
      int offset;
698
      char error_number[16];
699
      for (offset = 0; offset<15; offset++)
700
      {
701
         error_number[offset] = error_message[offset + 1];
702
         if (error_message[offset] == ' ')
703
            break;
704
      }
705
706
 
707
      {
708
         error_number[offset - 1] = '\0';
709
         fprintf(stderr, "libpng error no. %s: %s",
710
             error_number, error_message + offset + 1);
711
         fprintf(stderr, PNG_STRING_NEWLINE);
712
      }
713
714
 
715
      {
716
         fprintf(stderr, "libpng error: %s, offset=%d",
717
             error_message, offset);
718
         fprintf(stderr, PNG_STRING_NEWLINE);
719
      }
720
   }
721
   else
722
#endif
723
   {
724
      fprintf(stderr, "libpng error: %s", error_message ? error_message :
725
         "undefined");
726
      fprintf(stderr, PNG_STRING_NEWLINE);
727
   }
728
#else
729
   PNG_UNUSED(error_message) /* Make compiler happy */
730
#endif
731
   png_longjmp(png_ptr, 1);
732
}
733
734
 
735
png_longjmp,(png_const_structrp png_ptr, int val),PNG_NORETURN)
736
{
737
#ifdef PNG_SETJMP_SUPPORTED
738
   if (png_ptr && png_ptr->longjmp_fn && png_ptr->jmp_buf_ptr)
739
      png_ptr->longjmp_fn(*png_ptr->jmp_buf_ptr, val);
740
#endif
741
742
 
743
   PNG_ABORT();
744
}
745
746
 
747
/* This function is called when there is a warning, but the library thinks
748
 * it can continue anyway.  Replacement functions don't have to do anything
749
 * here if you don't want them to.  In the default configuration, png_ptr is
750
 * not used, but it is passed in case it may be useful.
751
 */
752
static void /* PRIVATE */
753
png_default_warning(png_const_structrp png_ptr, png_const_charp warning_message)
754
{
755
#ifdef PNG_CONSOLE_IO_SUPPORTED
756
#  ifdef PNG_ERROR_NUMBERS_SUPPORTED
757
   if (*warning_message == PNG_LITERAL_SHARP)
758
   {
759
      int offset;
760
      char warning_number[16];
761
      for (offset = 0; offset < 15; offset++)
762
      {
763
         warning_number[offset] = warning_message[offset + 1];
764
         if (warning_message[offset] == ' ')
765
            break;
766
      }
767
768
 
769
      {
770
         warning_number[offset + 1] = '\0';
771
         fprintf(stderr, "libpng warning no. %s: %s",
772
             warning_number, warning_message + offset);
773
         fprintf(stderr, PNG_STRING_NEWLINE);
774
      }
775
776
 
777
      {
778
         fprintf(stderr, "libpng warning: %s",
779
             warning_message);
780
         fprintf(stderr, PNG_STRING_NEWLINE);
781
      }
782
   }
783
   else
784
#  endif
785
786
 
787
      fprintf(stderr, "libpng warning: %s", warning_message);
788
      fprintf(stderr, PNG_STRING_NEWLINE);
789
   }
790
#else
791
   PNG_UNUSED(warning_message) /* Make compiler happy */
792
#endif
793
   PNG_UNUSED(png_ptr) /* Make compiler happy */
794
}
795
#endif /* PNG_WARNINGS_SUPPORTED */
796
797
 
798
 * of handling errors and warnings.  Note that the error function MUST NOT
799
 * return to the calling routine or serious problems will occur.  The return
800
 * method used in the default routine calls longjmp(png_ptr->jmp_buf_ptr, 1)
801
 */
802
void PNGAPI
803
png_set_error_fn(png_structrp png_ptr, png_voidp error_ptr,
804
    png_error_ptr error_fn, png_error_ptr warning_fn)
805
{
806
   if (png_ptr == NULL)
807
      return;
808
809
 
810
   png_ptr->error_fn = error_fn;
811
#ifdef PNG_WARNINGS_SUPPORTED
812
   png_ptr->warning_fn = warning_fn;
813
#else
814
   PNG_UNUSED(warning_fn)
815
#endif
816
}
817
818
 
819
 
820
 * functions.  The application should free any memory associated with this
821
 * pointer before png_write_destroy and png_read_destroy are called.
822
 */
823
png_voidp PNGAPI
824
png_get_error_ptr(png_const_structrp png_ptr)
825
{
826
   if (png_ptr == NULL)
827
      return NULL;
828
829
 
830
}
831
832
 
833
 
834
void PNGAPI
835
png_set_strip_error_numbers(png_structrp png_ptr, png_uint_32 strip_mode)
836
{
837
   if (png_ptr != NULL)
838
   {
839
      png_ptr->flags &=
840
         ((~(PNG_FLAG_STRIP_ERROR_NUMBERS |
841
         PNG_FLAG_STRIP_ERROR_TEXT))&strip_mode);
842
   }
843
}
844
#endif
845
846
 
847
   defined(PNG_SIMPLIFIED_WRITE_SUPPORTED)
848
   /* Currently the above both depend on SETJMP_SUPPORTED, however it would be
849
    * possible to implement without setjmp support just so long as there is some
850
    * way to handle the error return here:
851
    */
852
PNG_FUNCTION(void /* PRIVATE */,
853
png_safe_error,(png_structp png_nonconst_ptr, png_const_charp error_message),
854
   PNG_NORETURN)
855
{
856
   const png_const_structrp png_ptr = png_nonconst_ptr;
857
   png_imagep image = png_voidcast(png_imagep, png_ptr->error_ptr);
858
859
 
860
    * that is already there:
861
    */
862
   if (image != NULL)
863
   {
864
      png_safecat(image->message, (sizeof image->message), 0, error_message);
865
      image->warning_or_error |= PNG_IMAGE_ERROR;
866
867
 
868
       * C++ compilation too is pretty tricky: C++ wants a pointer to the first
869
       * element of a jmp_buf, but C doesn't tell us the type of that.
870
       */
871
      if (image->opaque != NULL && image->opaque->error_buf != NULL)
872
         longjmp(png_control_jmp_buf(image->opaque), 1);
873
874
 
875
      {
876
         size_t pos = png_safecat(image->message, (sizeof image->message), 0,
877
            "bad longjmp: ");
878
         png_safecat(image->message, (sizeof image->message), pos,
879
             error_message);
880
      }
881
   }
882
883
 
884
   abort();
885
}
886
887
 
888
void /* PRIVATE */
889
png_safe_warning(png_structp png_nonconst_ptr, png_const_charp warning_message)
890
{
891
   const png_const_structrp png_ptr = png_nonconst_ptr;
892
   png_imagep image = png_voidcast(png_imagep, png_ptr->error_ptr);
893
894
 
895
   if (image->warning_or_error == 0)
896
   {
897
      png_safecat(image->message, (sizeof image->message), 0, warning_message);
898
      image->warning_or_error |= PNG_IMAGE_WARNING;
899
   }
900
}
901
#endif
902
903
 
904
png_safe_execute(png_imagep image_in, int (*function)(png_voidp), png_voidp arg)
905
{
906
   volatile png_imagep image = image_in;
907
   volatile int result;
908
   volatile png_voidp saved_error_buf;
909
   jmp_buf safe_jmpbuf;
910
911
 
912
   saved_error_buf = image->opaque->error_buf;
913
   result = setjmp(safe_jmpbuf) == 0;
914
915
 
916
   {
917
918
 
919
      result = function(arg);
920
   }
921
922
 
923
924
 
925
   if (!result)
926
      png_image_free(image);
927
928
 
929
}
930
#endif /* SIMPLIFIED READ/WRITE */
931
#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */
932