Subversion Repositories Kolibri OS

Rev

Rev 6733 | Details | Compare with Previous | Last modification | View Log | RSS feed

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