Subversion Repositories Kolibri OS

Rev

Rev 6779 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
8341 dunkaist 1
 
2
3
 
4
; Copyright (c) 1998-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.inc
11
12
 
13
; into the info struct, and during writes to store application data
14
; into the info struct for writing into the file.  This abstracts the
15
; info struct and allows us to change the structure in the future.
16
17
 
18
 
19
align 4
20
proc png_set_bKGD uses ecx edi esi, png_ptr:dword, info_ptr:dword, background:dword
21
	png_debug1 1, 'in %s storage function', 'bKGD'
22
23
 
24
	je .end_f
25
	mov edi,[info_ptr]
26
	cmp edi,0
27
	je .end_f
28
	mov esi,[background]
29
	cmp esi,0
30
	je .end_f ;if (..==0 || ..==0 || ..==0) return
31
32
 
33
	add edi,png_info_def.background
34
	mov ecx,sizeof.png_color_16
35
	rep movsb
36
.end_f:
37
	ret
38
endp
39
40
 
41
;    png_fixed_point white_x, png_fixed_point white_y, png_fixed_point red_x,
42
;    png_fixed_point red_y, png_fixed_point green_x, png_fixed_point green_y,
43
;    png_fixed_point blue_x, png_fixed_point blue_y)
44
align 4
45
proc png_set_cHRM_fixed, png_ptr:dword, info_ptr:dword,\
46
	white_x:dword, white_y:dword, red_x:dword, red_y:dword,\
47
	green_x:dword, green_y:dword, blue_x:dword, blue_y:dword
48
;   png_xy xy;
49
50
 
51
52
 
53
;      return;
54
55
 
56
;   xy.redy = red_y;
57
;   xy.greenx = green_x;
58
;   xy.greeny = green_y;
59
;   xy.bluex = blue_x;
60
;   xy.bluey = blue_y;
61
;   xy.whitex = white_x;
62
;   xy.whitey = white_y;
63
64
 
65
;       2/* override with app values*/) != 0)
66
;      info_ptr->colorspace.flags |= PNG_COLORSPACE_FROM_cHRM;
67
68
 
69
.end_f:
70
	ret
71
endp
72
73
 
74
;    png_fixed_point int_red_X, png_fixed_point int_red_Y,
75
;    png_fixed_point int_red_Z, png_fixed_point int_green_X,
76
;    png_fixed_point int_green_Y, png_fixed_point int_green_Z,
77
;    png_fixed_point int_blue_X, png_fixed_point int_blue_Y,
78
;    png_fixed_point int_blue_Z)
79
align 4
80
proc png_set_cHRM_XYZ_fixed uses edi esi, png_ptr:dword, info_ptr:dword,\
81
	int_red_X:dword, int_red_Y:dword, int_red_Z:dword,\
82
	int_green_X:dword, int_green_Y:dword, int_green_Z:dword,\
83
	int_blue_X:dword, int_blue_Y:dword, int_blue_Z:dword
84
;   png_XYZ XYZ;
85
86
 
87
88
 
89
	cmp edi,0
90
	je .end_f
91
	mov esi,[info_ptr]
92
	cmp esi,0
93
	je .end_f ;if (..==0 || ..==0) return
94
95
 
96
;   XYZ.red_Y = int_red_Y;
97
;   XYZ.red_Z = int_red_Z;
98
;   XYZ.green_X = int_green_X;
99
;   XYZ.green_Y = int_green_Y;
100
;   XYZ.green_Z = int_green_Z;
101
;   XYZ.blue_X = int_blue_X;
102
;   XYZ.blue_Y = int_blue_Y;
103
;   XYZ.blue_Z = int_blue_Z;
104
105
 
106
;       &XYZ, 2) != 0)
107
;      info_ptr->colorspace.flags |= PNG_COLORSPACE_FROM_cHRM;
108
109
 
110
.end_f:
111
	ret
112
endp
113
114
 
115
;    double white_x, double white_y, double red_x, double red_y,
116
;    double green_x, double green_y, double blue_x, double blue_y)
117
align 4
118
proc png_set_cHRM, png_ptr:dword, info_ptr:dword,\
119
	white_x:dword, white_y:dword, red_x:dword, red_y:dword,\
120
	green_x:dword, green_y:dword, blue_x:dword, blue_y:dword
121
;   png_set_cHRM_fixed(png_ptr, info_ptr,
122
;       png_fixed(png_ptr, white_x, "cHRM White X"),
123
;       png_fixed(png_ptr, white_y, "cHRM White Y"),
124
;       png_fixed(png_ptr, red_x, "cHRM Red X"),
125
;       png_fixed(png_ptr, red_y, "cHRM Red Y"),
126
;       png_fixed(png_ptr, green_x, "cHRM Green X"),
127
;       png_fixed(png_ptr, green_y, "cHRM Green Y"),
128
;       png_fixed(png_ptr, blue_x, "cHRM Blue X"),
129
;       png_fixed(png_ptr, blue_y, "cHRM Blue Y"));
130
	ret
131
endp
132
133
 
134
;    double red_Y, double red_Z, double green_X, double green_Y, double green_Z,
135
;    double blue_X, double blue_Y, double blue_Z)
136
align 4
137
proc png_set_cHRM_XYZ, png_ptr:dword, info_ptr:dword, red_X:dword, red_Y:dword, red_Z:dword, green_X:dword, green_Y:dword, green_Z:dword, blue_X:dword, blue_Y:dword, blue_Z:dword
138
;   png_set_cHRM_XYZ_fixed(png_ptr, info_ptr,
139
;       png_fixed(png_ptr, red_X, "cHRM Red X"),
140
;       png_fixed(png_ptr, red_Y, "cHRM Red Y"),
141
;       png_fixed(png_ptr, red_Z, "cHRM Red Z"),
142
;       png_fixed(png_ptr, green_X, "cHRM Green X"),
143
;       png_fixed(png_ptr, green_Y, "cHRM Green Y"),
144
;       png_fixed(png_ptr, green_Z, "cHRM Green Z"),
145
;       png_fixed(png_ptr, blue_X, "cHRM Blue X"),
146
;       png_fixed(png_ptr, blue_Y, "cHRM Blue Y"),
147
;       png_fixed(png_ptr, blue_Z, "cHRM Blue Z"));
148
	ret
149
endp
150
151
 
152
align 4
153
proc png_set_gAMA_fixed uses eax edi esi, png_ptr:dword, info_ptr:dword, file_gamma:dword
154
	png_debug1 1, 'in %s storage function', 'gAMA'
155
156
 
157
	cmp edi,0
158
	je .end_f
159
	mov esi,[info_ptr]
160
	cmp esi,0
161
	je .end_f ;if (..== 0 || ..== 0) return
162
163
 
164
	add eax,png_info_def.colorspace
165
	stdcall png_colorspace_set_gamma, edi, eax, [file_gamma]
166
	stdcall png_colorspace_sync_info, edi, esi
167
.end_f:
168
	ret
169
endp
170
171
 
172
align 4
173
proc png_set_gAMA uses eax, png_ptr:dword, info_ptr:dword, file_gamma:dword
174
	cStr ,'png_set_gAMA'
175
	stdcall png_fixed, [png_ptr], [file_gamma], eax
176
	stdcall png_set_gAMA_fixed, [png_ptr], [info_ptr], eax
177
	ret
178
endp
179
180
 
181
align 4
182
proc png_set_hIST uses edi esi, png_ptr:dword, info_ptr:dword, hist:dword
183
;   int i;
184
185
 
186
187
 
188
	cmp edi,0
189
	je .end_f
190
	mov esi,[info_ptr]
191
	cmp esi,0
192
	je .end_f ;if (..== 0 || ..== 0) return
193
194
 
195
;       > PNG_MAX_PALETTE_LENGTH)
196
;   {
197
;      png_warning(png_ptr,
198
;          "Invalid palette size, hIST allocation skipped");
199
200
 
201
;   }
202
203
 
204
205
 
206
	; version 1.2.1
207
208
 
209
;       PNG_MAX_PALETTE_LENGTH * (sizeof (uint_16)));
210
211
 
212
;   {
213
;      png_warning(png_ptr, "Insufficient memory for hIST chunk data");
214
215
 
216
;   }
217
218
 
219
220
 
221
;      info_ptr->hist[i] = hist[i];
222
223
 
224
.end_f:
225
	ret
226
endp
227
228
 
229
;    uint_32 width, uint_32 height, int bit_depth,
230
;    int color_type, int interlace_type, int compression_type, int filter_type)
231
align 4
232
proc png_set_IHDR, png_ptr:dword, info_ptr:dword,\
233
	width:dword, height:dword, bit_depth:dword, color_type:dword,\
234
	interlace_type:dword, compression_type:dword, filter_type:dword
235
	png_debug1 1, 'in %s storage function', 'IHDR'
236
pushad
237
	mov edi,[png_ptr]
238
	cmp edi,0
239
	je .end_f
240
	mov esi,[info_ptr]
241
	cmp esi,0
242
	je .end_f ;if (..== 0 || ..== 0) return
243
244
 
245
	mov [esi+png_info_def.width],eax
246
	mov eax,[height]
247
	mov [esi+png_info_def.height],eax
248
	movzx eax,byte[filter_type]
249
	mov [esi+png_info_def.filter_type],al
250
	push eax
251
	movzx eax,byte[compression_type]
252
	mov [esi+png_info_def.compression_type],al
253
	push eax
254
	movzx eax,byte[interlace_type]
255
	mov [esi+png_info_def.interlace_type],al
256
	push eax
257
	movzx ebx,byte[color_type]
258
	mov [esi+png_info_def.color_type],bl
259
	push ebx
260
	movzx ecx,byte[bit_depth]
261
	mov [esi+png_info_def.bit_depth],cl
262
263
 
264
		;, color_type, interlace_type, compression_type, filter_type
265
266
 
267
	jne @f ;if (..==..)
268
		mov byte[esi+png_info_def.channels], 1
269
		jmp .end0
270
	@@:
271
	mov eax,ebx
272
	and eax,PNG_COLOR_MASK_COLOR
273
	cmp eax,0
274
	je @f ;else if (..!=0)
275
		mov byte[esi+png_info_def.channels], 3
276
		jmp .end0
277
	@@: ;else
278
		mov byte[esi+png_info_def.channels], 1
279
	.end0:
280
281
 
282
	and eax,PNG_COLOR_MASK_ALPHA
283
	cmp eax,0
284
	je @f ;else if (..!=0)
285
		inc byte[esi+png_info_def.channels]
286
	@@:
287
288
 
289
	imul eax,ecx
290
	mov byte[esi+png_info_def.pixel_depth],al ;channels * bit_depth
291
292
 
293
	mov [esi+png_info_def.rowbytes], eax
294
.end_f:
295
popad
296
	ret
297
endp
298
299
 
300
;void (png_structrp png_ptr, png_inforp info_ptr,
301
;    int_32 offset_x, int_32 offset_y, int unit_type)
302
align 4
303
proc png_set_oFFs uses eax esi, png_ptr:dword, info_ptr:dword, offset_x:dword, offset_y:dword, unit_type:dword
304
	png_debug1 1, 'in %s storage function', 'oFFs'
305
306
 
307
	je @f
308
	mov esi,[info_ptr]
309
	cmp esi,0
310
	je @f ;if (..==0 || ..==0) return
311
312
 
313
	mov [esi+png_info_def.x_offset],eax
314
	mov eax,[offset_y]
315
	mov [esi+png_info_def.y_offset],eax
316
	mov al,[unit_type]
317
	mov [esi+png_info_def.offset_unit_type],al
318
	or dword[esi+png_info_def.valid], PNG_INFO_oFFs
319
	@@:
320
	ret
321
endp
322
323
 
324
;    charp purpose, int_32 X0, int_32 X1, int type,
325
;    int nparams, charp units, charpp params)
326
align 4
327
proc png_set_pCAL uses edi esi, png_ptr:dword, info_ptr:dword, purpose:dword, X0:dword, X1:dword, type:dword, nparams:dword, units:dword, params:dword
328
;   png_size_t length;
329
;   int i;
330
331
 
332
333
 
334
	cmp edi,0
335
	je .end_f
336
	mov esi,[info_ptr]
337
	cmp esi,0
338
	je .end_f
339
	cmp dword[purpose],0
340
	je .end_f
341
	cmp dword[units],0
342
	je .end_f
343
	cmp dword[nparams],0
344
	jle @f
345
	cmp dword[params],0
346
	jne @f
347
		jmp .end_f
348
	@@: ;if (..==0 || ..==0 || ..==0 || ..==0 || (nparams > 0 && params == 0)) return
349
350
 
351
	png_debug1 3, 'allocating purpose for info (%lu bytes)','(unsigned long)length'
352
353
 
354
355
 
356
	cmp dword[type],0
357
	jl @f
358
	cmp dword[type],3
359
	jle .end0 ;if (..<0 || ..>3)
360
	@@:
361
		png_error edi, 'Invalid pCAL equation type'
362
	.end0:
363
364
 
365
	jl @f
366
	cmp dword[nparams],255
367
	jle .end1 ;if (..<0 || ..>255)
368
	@@:
369
		png_error edi, 'Invalid pCAL parameter count'
370
	.end1:
371
372
 
373
;   for (i=0; i
374
;   {
375
;      if (params[i] == NULL ||
376
;          !png_check_fp_string(params[i], strlen(params[i])))
377
;         png_error(png_ptr, "Invalid format for pCAL parameter");
378
;   }
379
380
 
381
382
 
383
;   {
384
;      png_warning(png_ptr, "Insufficient memory for pCAL purpose");
385
386
 
387
;   }
388
389
 
390
391
 
392
;   info_ptr->pcal_X0 = X0;
393
;   info_ptr->pcal_X1 = X1;
394
;   info_ptr->pcal_type = (byte)type;
395
;   info_ptr->pcal_nparams = (byte)nparams;
396
397
 
398
	png_debug1 3, 'allocating units for info (%lu bytes)','(unsigned long)length'
399
400
 
401
402
 
403
;   {
404
;      png_warning(png_ptr, "Insufficient memory for pCAL units");
405
406
 
407
;   }
408
409
 
410
411
 
412
;       (png_size_t)((nparams + 1) * (sizeof (charp))));
413
414
 
415
;   {
416
;      png_warning(png_ptr, "Insufficient memory for pCAL params");
417
418
 
419
;   }
420
421
 
422
423
 
424
;   {
425
;      length = strlen(params[i]) + 1;
426
;      png_debug2(3, "allocating parameter %d for info (%lu bytes)", i,
427
;          (unsigned long)length);
428
429
 
430
431
 
432
;      {
433
;         png_warning(png_ptr, "Insufficient memory for pCAL parameter");
434
435
 
436
;      }
437
438
 
439
;   }
440
441
 
442
	or dword[esi+png_info_def.free_me],PNG_FREE_PCAL
443
.end_f:
444
	ret
445
endp
446
447
 
448
;    int unit, charp swidth, charp sheight)
449
align 4
450
proc png_set_sCAL_s, png_ptr:dword, info_ptr:dword, unit:dword, swidth:dword, sheight:dword
451
;   png_size_t lengthw = 0, lengthh = 0;
452
453
 
454
455
 
456
;      return;
457
458
 
459
	; unit unless this is an API call.)
460
461
 
462
;      png_error(png_ptr, "Invalid sCAL unit");
463
464
 
465
;       swidth[0] == 45 /* '-' */ || !png_check_fp_string(swidth, lengthw))
466
;      png_error(png_ptr, "Invalid sCAL width");
467
468
 
469
;       sheight[0] == 45 /* '-' */ || !png_check_fp_string(sheight, lengthh))
470
;      png_error(png_ptr, "Invalid sCAL height");
471
472
 
473
474
 
475
476
 
477
478
 
479
480
 
481
;   {
482
;      png_warning(png_ptr, "Memory allocation failed while processing sCAL");
483
484
 
485
;   }
486
487
 
488
489
 
490
491
 
492
493
 
494
495
 
496
;   {
497
;      png_free (png_ptr, info_ptr->scal_s_width);
498
;      info_ptr->scal_s_width = NULL;
499
500
 
501
502
 
503
;   }
504
505
 
506
;
507
;   info_ptr->valid |= PNG_INFO_sCAL;
508
;   info_ptr->free_me |= PNG_FREE_SCAL;
509
	ret
510
endp
511
512
 
513
;    double width, double height)
514
align 4
515
proc png_set_sCAL, png_ptr:dword, info_ptr:dword, unit:dword, width:dword, height:dword
516
	png_debug1 1, 'in %s storage function', 'sCAL'
517
518
 
519
;   if (width <= 0)
520
;      png_warning(png_ptr, "Invalid sCAL width ignored");
521
522
 
523
;      png_warning(png_ptr, "Invalid sCAL height ignored");
524
525
 
526
;   {
527
	; Convert 'width' and 'height' to ASCII.
528
;      char swidth[PNG_sCAL_MAX_DIGITS+1];
529
;      char sheight[PNG_sCAL_MAX_DIGITS+1];
530
531
 
532
;          PNG_sCAL_PRECISION);
533
;      png_ascii_from_fp(png_ptr, sheight, (sizeof sheight), height,
534
;          PNG_sCAL_PRECISION);
535
536
 
537
;   }
538
	ret
539
endp
540
541
 
542
;    png_fixed_point width, png_fixed_point height)
543
align 4
544
proc png_set_sCAL_fixed uses ebx ecx edi, png_ptr:dword, info_ptr:dword, unit:dword, width:dword, height:dword
545
locals
546
	swidth  rb PNG_sCAL_MAX_DIGITS+1 ;char[]
547
	sheight rb PNG_sCAL_MAX_DIGITS+1 ;char[]
548
endl
549
	png_debug1 1, 'in %s storage function', 'sCAL'
550
	mov edi,[png_ptr]
551
552
 
553
	cmp dword[width],0
554
	jg @f ;if (..<=0)
555
		png_warning edi, 'Invalid sCAL width ignored'
556
		jmp .end0
557
	@@:
558
	cmp dword[height],0
559
	jg @f ;else if (..<=0)
560
		png_warning edi, 'Invalid sCAL height ignored'
561
		jmp .end0
562
	@@: ;else
563
		; Convert 'width' and 'height' to ASCII.
564
		mov ebx,ebp
565
		sub ebx,PNG_sCAL_MAX_DIGITS+1 ;sheight
566
		mov ecx,ebx
567
		sub ecx,PNG_sCAL_MAX_DIGITS+1 ;swidth
568
569
 
570
		stdcall png_ascii_from_fixed, edi, ebx, PNG_sCAL_MAX_DIGITS+1, [height]
571
572
 
573
	.end0:
574
	ret
575
endp
576
577
 
578
;    uint_32 res_x, uint_32 res_y, int unit_type)
579
align 4
580
proc png_set_pHYs, png_ptr:dword, info_ptr:dword, res_x:dword, res_y:dword, unit_type:dword
581
	png_debug1 1, 'in %s storage function', 'pHYs'
582
583
 
584
;      return;
585
586
 
587
;   info_ptr->y_pixels_per_unit = res_y;
588
;   info_ptr->phys_unit_type = (byte)unit_type;
589
;   info_ptr->valid |= PNG_INFO_pHYs;
590
	ret
591
endp
592
593
 
594
align 4
595
proc png_set_PLTE uses eax edi esi, png_ptr:dword, info_ptr:dword, palette:dword, num_palette:dword
596
;   uint_32 max_palette_length;
597
598
 
599
600
 
601
	cmp edi,0
602
	je .end_f
603
	mov esi,[info_ptr]
604
	cmp esi,0
605
	je .end_f ;if (..==0 || ..==0) return
606
607
 
608
;      (1 << info_ptr->bit_depth) : PNG_MAX_PALETTE_LENGTH;
609
610
 
611
;   {
612
;      if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
613
;         png_error(png_ptr, "Invalid palette length");
614
615
 
616
;      {
617
;         png_warning(png_ptr, "Invalid palette length");
618
619
 
620
;      }
621
;   }
622
623
 
624
;      (num_palette == 0
625
if PNG_MNG_FEATURES_SUPPORTED eq 1
626
;            && (png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE) == 0
627
end if
628
;      ))
629
;   {
630
;      png_error(png_ptr, "Invalid palette");
631
;   }
632
633
 
634
	; we do it for backward compatibility with the way the png_handle_tRNS
635
	; function used to do the allocation.
636
637
 
638
	; the palette inside png_struct on read.
639
640
 
641
642
 
643
	; of num_palette entries, in case of an invalid PNG file or incorrect
644
	; call to png_set_PLTE() with too-large sample values.
645
646
 
647
;       PNG_MAX_PALETTE_LENGTH * (sizeof (png_color)));
648
649
 
650
;      memcpy(png_ptr->palette, palette, num_palette * (sizeof (png_color)));
651
	mov eax,[edi+png_struct.palette]
652
	mov [esi+png_info_def.palette],eax
653
;   info_ptr->num_palette = png_ptr->num_palette = (uint_16)num_palette;
654
655
 
656
	or dword[esi+png_info_def.valid], PNG_INFO_PLTE
657
.end_f:
658
	ret
659
endp
660
661
 
662
align 4
663
proc png_set_sBIT, png_ptr:dword, info_ptr:dword, sig_bit:dword
664
	png_debug1 1, 'in %s storage function', 'sBIT'
665
666
 
667
;      return;
668
669
 
670
;   info_ptr->valid |= PNG_INFO_sBIT;
671
.end_f:
672
	ret
673
endp
674
675
 
676
align 4
677
proc png_set_sRGB uses eax edi esi, png_ptr:dword, info_ptr:dword, srgb_intent:dword
678
	png_debug1 1, 'in %s storage function', 'sRGB'
679
680
 
681
	cmp edi,0
682
	je .end_f
683
	mov esi,[info_ptr]
684
	cmp esi,0
685
	je .end_f ;if (..==0 || ..==0)
686
687
 
688
	add eax,png_info_def.colorspace
689
	stdcall png_colorspace_set_sRGB, edi, eax, [srgb_intent]
690
	stdcall png_colorspace_sync_info, edi, esi
691
.end_f:
692
	ret
693
endp
694
695
 
696
align 4
697
proc png_set_sRGB_gAMA_and_cHRM, png_ptr:dword, info_ptr:dword, srgb_intent:dword
698
	png_debug1 1, 'in %s storage function', 'sRGB_gAMA_and_cHRM'
699
700
 
701
;      return;
702
703
 
704
;       srgb_intent) != 0)
705
;   {
706
	; This causes the gAMA and cHRM to be written too
707
;      info_ptr->colorspace.flags |=
708
;         PNG_COLORSPACE_FROM_gAMA|PNG_COLORSPACE_FROM_cHRM;
709
;   }
710
711
 
712
.end_f:
713
	ret
714
endp
715
716
 
717
;    charp name, int compression_type, bytep profile, uint_32 proflen)
718
align 4
719
proc png_set_iCCP uses edi esi, png_ptr:dword, info_ptr:dword, name:dword, compression_type:dword, profile:dword, proflen:dword
720
;   charp new_iccp_name;
721
;   bytep new_iccp_profile;
722
;   png_size_t length;
723
724
 
725
726
 
727
;   if (png_ptr == NULL || info_ptr == NULL || name == NULL || profile == NULL)
728
;      return;
729
730
 
731
;      png_app_error(png_ptr, "Invalid iCCP compression method");
732
733
 
734
	; override previously set app cHRM or gAMA here (because likely as not the
735
	; application knows better than libpng what the correct values are.)  Pass
736
	; the info_ptr color_type field to png_colorspace_set_ICC because in the
737
	; write case it has not yet been stored in png_ptr.
738
739
 
740
;      int result = png_colorspace_set_ICC(png_ptr, &info_ptr->colorspace, name,
741
;          proflen, profile, info_ptr->color_type);
742
743
 
744
745
 
746
;      if (result == 0)
747
;         return;
748
749
 
750
;      info_ptr->colorspace.flags |=
751
;         PNG_COLORSPACE_FROM_gAMA|PNG_COLORSPACE_FROM_cHRM;
752
;   }
753
754
 
755
;   new_iccp_name = png_malloc_warn(png_ptr, length);
756
757
 
758
;   {
759
;      png_benign_error(png_ptr, "Insufficient memory to process iCCP chunk");
760
;      return;
761
;   }
762
763
 
764
;   new_iccp_profile = png_malloc_warn(png_ptr, proflen);
765
766
 
767
;   {
768
;      png_free(png_ptr, new_iccp_name);
769
;      png_benign_error(png_ptr,
770
;          "Insufficient memory to process iCCP profile");
771
;      return;
772
;   }
773
774
 
775
776
 
777
778
 
779
;   info_ptr->iccp_name = new_iccp_name;
780
;   info_ptr->iccp_profile = new_iccp_profile;
781
	or dword[esi+png_info_def.free_me],PNG_FREE_ICCP
782
	or dword[esi+png_info_def.valid],PNG_INFO_iCCP
783
	ret
784
endp
785
786
 
787
align 4
788
proc png_set_text uses eax edi, png_ptr:dword, info_ptr:dword, text_ptr:dword, num_text:dword
789
	mov edi,[png_ptr]
790
	stdcall png_set_text_2, edi, [info_ptr], [text_ptr], [num_text]
791
792
 
793
	je @f ;if (..!=0)
794
		png_error edi, 'Insufficient memory to store text'
795
	@@:
796
	ret
797
endp
798
799
 
800
;    png_textp text_ptr, int num_text)
801
align 4
802
proc png_set_text_2, png_ptr:dword, info_ptr:dword, text_ptr:dword, num_text:dword
803
;   int i;
804
805
 
806
807
 
808
;      return(0);
809
810
 
811
	; to hold all of the incoming text_ptr objects.  This compare can't overflow
812
	; because max_text >= num_text (anyway, subtract of two positive integers
813
	; can't overflow in any case.)
814
815
 
816
;   {
817
;      int old_num_text = info_ptr->num_text;
818
;      int max_text;
819
;      png_textp new_text = NULL;
820
821
 
822
;      max_text = old_num_text;
823
;      if (num_text <= INT_MAX - max_text)
824
;      {
825
;         max_text += num_text;
826
827
 
828
;         if (max_text < INT_MAX-8)
829
;            max_text = (max_text + 8) & ~0x7;
830
831
 
832
;            max_text = INT_MAX;
833
834
 
835
	; the overflow checks.
836
837
 
838
;             info_ptr->text, old_num_text, max_text-old_num_text,
839
;             sizeof *new_text);
840
;      }
841
842
 
843
;      {
844
;         png_chunk_report(png_ptr, "too many text chunks",
845
;             PNG_CHUNK_WRITE_ERROR);
846
847
 
848
;      }
849
850
 
851
852
 
853
;      info_ptr->free_me |= PNG_FREE_TEXT;
854
;      info_ptr->max_text = max_text;
855
;      /* num_text is adjusted below as the entries are copied in */
856
857
 
858
;   }
859
860
 
861
;   {
862
;      size_t text_length, key_len;
863
;      size_t lang_len, lang_key_len;
864
;      png_textp textp = &(info_ptr->text[info_ptr->num_text]);
865
866
 
867
;          continue;
868
869
 
870
;          text_ptr[i].compression >= PNG_TEXT_COMPRESSION_LAST)
871
;      {
872
;         png_chunk_report(png_ptr, "text compression mode is out of range",
873
;             PNG_CHUNK_WRITE_ERROR);
874
;         continue;
875
;      }
876
877
 
878
879
 
880
;      {
881
;         lang_len = 0;
882
;         lang_key_len = 0;
883
;      }
884
885
 
886
if PNG_iTXt_SUPPORTED eq 1
887
;      {
888
;         /* Set iTXt data */
889
890
 
891
;            lang_len = strlen(text_ptr[i].lang);
892
;
893
;         else
894
;            lang_len = 0;
895
896
 
897
;            lang_key_len = strlen(text_ptr[i].lang_key);
898
899
 
900
;            lang_key_len = 0;
901
;      }
902
else ;iTXt
903
;      {
904
;         png_chunk_report(png_ptr, "iTXt chunk not supported",
905
;             PNG_CHUNK_WRITE_ERROR);
906
;         continue;
907
;      }
908
end if
909
910
 
911
;      {
912
;         text_length = 0;
913
if PNG_iTXt_SUPPORTED eq 1
914
;         if (text_ptr[i].compression > 0)
915
;            textp->compression = PNG_ITXT_COMPRESSION_NONE;
916
917
 
918
end if
919
;            textp->compression = PNG_TEXT_COMPRESSION_NONE;
920
;      }
921
922
 
923
;      {
924
;         text_length = strlen(text_ptr[i].text);
925
;         textp->compression = text_ptr[i].compression;
926
;      }
927
928
 
929
;          key_len + text_length + lang_len + lang_key_len + 4);
930
931
 
932
;      {
933
;         png_chunk_report(png_ptr, "text chunk: out of memory",
934
;             PNG_CHUNK_WRITE_ERROR);
935
936
 
937
;      }
938
939
 
940
;          (unsigned long)(uint_32)
941
;          (key_len + lang_len + lang_key_len + text_length + 4),
942
;          textp->key);
943
944
 
945
;      *(textp->key + key_len) = '\0';
946
947
 
948
;      {
949
;         textp->lang = textp->key + key_len + 1;
950
;         memcpy(textp->lang, text_ptr[i].lang, lang_len);
951
;         *(textp->lang + lang_len) = '\0';
952
;         textp->lang_key = textp->lang + lang_len + 1;
953
;         memcpy(textp->lang_key, text_ptr[i].lang_key, lang_key_len);
954
;         *(textp->lang_key + lang_key_len) = '\0';
955
;         textp->text = textp->lang_key + lang_key_len + 1;
956
;      }
957
958
 
959
;      {
960
;         textp->lang=NULL;
961
;         textp->lang_key=NULL;
962
;         textp->text = textp->key + key_len + 1;
963
;      }
964
965
 
966
;         memcpy(textp->text, text_ptr[i].text, text_length);
967
968
 
969
970
 
971
;      if (textp->compression > 0)
972
;      {
973
;         textp->text_length = 0;
974
;         textp->itxt_length = text_length;
975
;      }
976
977
 
978
end if
979
;      {
980
;         textp->text_length = text_length;
981
;         textp->itxt_length = 0;
982
;      }
983
984
 
985
;      png_debug1(3, "transferred text chunk %d", info_ptr->num_text);
986
;   }
987
988
 
989
.end_f:
990
	ret
991
endp
992
993
 
994
align 4
995
proc png_set_tIME uses eax ebx ecx edi esi, png_ptr:dword, info_ptr:dword, mod_time:dword
996
	png_debug1 1, 'in %s storage function', 'tIME'
997
998
 
999
	cmp ebx,0
1000
	je .end_f
1001
	mov edi,[info_ptr]
1002
	cmp edi,0
1003
	je .end_f
1004
	mov esi,[mod_time]
1005
	cmp esi,0
1006
	je .end_f
1007
	mov eax,[ebx+png_struct.mode]
1008
	and eax,PNG_WROTE_tIME
1009
	cmp eax,0
1010
	jne .end_f ;if (..==0 || ..==0 || ..==0 || ..!=0) return
1011
1012
 
1013
	je @f
1014
	cmp byte[esi+png_time.month],12
1015
	jg @f
1016
	cmp byte[esi+png_time.day],0
1017
	je @f
1018
	cmp byte[esi+png_time.day],31
1019
	jg @f
1020
	cmp byte[esi+png_time.hour],23
1021
	jg @f
1022
	cmp byte[esi+png_time.minute],59
1023
	jg @f
1024
	cmp byte[esi+png_time.second],60
1025
	jle .end0
1026
	@@: ;if (..==0 || ..>.. || ..==0 || ..>.. || ..>.. || ..>.. || ..>..)
1027
		png_warning ebx, 'Ignoring invalid time value'
1028
		jmp .end_f
1029
	.end0:
1030
1031
 
1032
	push edi
1033
	add edi,png_info_def.mod_time
1034
	rep movsb
1035
	pop edi
1036
	or dword[edi+png_info_def.valid],PNG_INFO_tIME
1037
.end_f:
1038
	ret
1039
endp
1040
1041
 
1042
;    bytep trans_alpha, int num_trans, png_color_16p trans_color)
1043
align 4
1044
proc png_set_tRNS, png_ptr:dword, info_ptr:dword, trans_alpha:dword, num_trans:dword, trans_color:dword
1045
	png_debug1 1, 'in %s storage function', 'tRNS'
1046
1047
 
1048
;      return;
1049
1050
 
1051
;   {
1052
	; It may not actually be necessary to set png_ptr->trans_alpha here;
1053
	; we do it for backward compatibility with the way the png_handle_tRNS
1054
	; function used to do the allocation.
1055
1056
 
1057
	; relies on png_set_tRNS storing the information in png_struct
1058
	; (otherwise it won't be there for the code in pngrtran.c).
1059
1060
 
1061
 
1062
1063
 
1064
;       {
1065
	; Changed from num_trans to PNG_MAX_PALETTE_LENGTH in version 1.2.1
1066
;          info_ptr->trans_alpha = png_malloc(png_ptr, PNG_MAX_PALETTE_LENGTH);
1067
;          memcpy(info_ptr->trans_alpha, trans_alpha, (png_size_t)num_trans);
1068
;       }
1069
;       png_ptr->trans_alpha = info_ptr->trans_alpha;
1070
;   }
1071
1072
 
1073
;   {
1074
if PNG_WARNINGS_SUPPORTED eq 1
1075
;      if (info_ptr->bit_depth < 16)
1076
;      {
1077
;         int sample_max = (1 << info_ptr->bit_depth) - 1;
1078
;
1079
;         if ((info_ptr->color_type == PNG_COLOR_TYPE_GRAY &&
1080
;             trans_color->gray > sample_max) ||
1081
;             (info_ptr->color_type == PNG_COLOR_TYPE_RGB &&
1082
;             (trans_color->red > sample_max ||
1083
;             trans_color->green > sample_max ||
1084
;             trans_color->blue > sample_max)))
1085
;            png_warning(png_ptr,
1086
;                "tRNS chunk has out-of-range samples for bit_depth");
1087
;      }
1088
end if
1089
1090
 
1091
1092
 
1093
;         num_trans = 1;
1094
;   }
1095
1096
 
1097
1098
 
1099
;   {
1100
;      info_ptr->valid |= PNG_INFO_tRNS;
1101
;      info_ptr->free_me |= PNG_FREE_TRNS;
1102
;   }
1103
	ret
1104
endp
1105
1106
 
1107
;void (png_structrp png_ptr,
1108
;    png_inforp info_ptr, png_sPLT_tp entries, int nentries)
1109
1110
 
1111
;                   to be added to the list of palettes
1112
;                   in the info structure.
1113
1114
 
1115
;                   added.
1116
1117
 
1118
proc png_set_sPLT, png_ptr:dword, info_ptr:dword, entries:dword, nentries:dword
1119
;   png_sPLT_tp np;
1120
1121
 
1122
;      return;
1123
1124
 
1125
	; overflows.  Notice that the parameters are (int) and (size_t)
1126
1127
 
1128
;       info_ptr->splt_palettes, info_ptr->splt_palettes_num, nentries,
1129
;       sizeof *np);
1130
1131
 
1132
;   {
1133
;      /* Out of memory or too many chunks */
1134
;      png_chunk_report(png_ptr, "too many sPLT chunks", PNG_CHUNK_WRITE_ERROR);
1135
1136
 
1137
;   }
1138
1139
 
1140
;   info_ptr->splt_palettes = np;
1141
;   info_ptr->free_me |= PNG_FREE_SPLT;
1142
1143
 
1144
1145
 
1146
;   {
1147
;      png_size_t length;
1148
1149
 
1150
;      if (entries->name == NULL || entries->entries == NULL)
1151
;      {
1152
;         /* png_handle_sPLT doesn't do this, so this is an app error */
1153
;         png_app_error(png_ptr, "png_set_sPLT: invalid sPLT");
1154
;         /* Just skip the invalid entry */
1155
;         continue;
1156
;      }
1157
1158
 
1159
1160
 
1161
	; on trying to add sPLT chunks.
1162
1163
 
1164
;      np->name = png_malloc_base(png_ptr, length);
1165
1166
 
1167
;         break;
1168
1169
 
1170
1171
 
1172
	; goes wrong; this code must free it.  png_malloc_array produces no
1173
	; warnings; use a png_chunk_report (below) if there is an error.
1174
1175
 
1176
;          entries->nentries, sizeof (png_sPLT_entry));
1177
1178
 
1179
;      {
1180
;         png_free(png_ptr, np->name);
1181
;         np->name = NULL;
1182
;         break;
1183
;      }
1184
1185
 
1186
	; This multiply can't overflow because png_malloc_array has already
1187
	; checked it when doing the allocation.
1188
1189
 
1190
;          entries->nentries * sizeof (png_sPLT_entry));
1191
1192
 
1193
	; count, so an invalid entry is not added.
1194
1195
 
1196
;      ++(info_ptr->splt_palettes_num);
1197
;      ++np;
1198
;   }
1199
;   while (++entries, --nentries);
1200
1201
 
1202
;      png_chunk_report(png_ptr, "sPLT out of memory", PNG_CHUNK_WRITE_ERROR);
1203
	ret
1204
endp
1205
;end if /* sPLT */
1206
1207
 
1208
;byte (png_structrp png_ptr, int location)
1209
align 4
1210
proc check_location, png_ptr:dword, location:dword
1211
;   location &= (PNG_HAVE_IHDR|PNG_HAVE_PLTE|PNG_AFTER_IDAT);
1212
1213
 
1214
	; change; previously the app had to use the
1215
	; png_set_unknown_chunk_location API below for each chunk.
1216
1217
 
1218
;   {
1219
;      /* Write struct, so unknown chunks come from the app */
1220
;      png_app_warning(png_ptr,
1221
;          "png_set_unknown_chunks now expects a valid location");
1222
;      /* Use the old behavior */
1223
;      location = (byte)(png_ptr->mode &
1224
;          (PNG_HAVE_IHDR|PNG_HAVE_PLTE|PNG_AFTER_IDAT));
1225
;   }
1226
1227
 
1228
	; png_set_unknown_chunks on a read pointer it must get the location right.
1229
1230
 
1231
;      png_error(png_ptr, "invalid location in png_set_unknown_chunks");
1232
1233
 
1234
	; significant bit in turn.
1235
1236
 
1237
;      location &= ~(location & -location);
1238
1239
 
1240
	; bits are significant.
1241
1242
 
1243
	ret
1244
endp
1245
1246
 
1247
;    png_inforp info_ptr, png_unknown_chunkp unknowns, int num_unknowns)
1248
align 4
1249
proc png_set_unknown_chunks uses edi esi, png_ptr:dword, info_ptr:dword, unknowns:dword, num_unknowns:dword
1250
;   png_unknown_chunkp np;
1251
1252
 
1253
	cmp edi,0
1254
	je .end_f
1255
	mov esi,[info_ptr]
1256
	cmp esi,0
1257
	je .end_f
1258
	cmp dword[num_unknowns],0
1259
	jle .end_f
1260
	cmp dword[unknowns],0
1261
	je .end_f ;if (..== 0 || ..== 0 || ..<=0 || ..==0) return
1262
1263
 
1264
	; time.  This code is hardly ever compiled - it's here because
1265
	; STORE_UNKNOWN_CHUNKS is set by both read and write code (compiling in this
1266
	; code) but may be meaningless if the read or write handling of unknown
1267
	; chunks is not compiled in.
1268
1269
 
1270
;      defined(PNG_READ_SUPPORTED)
1271
;      if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0)
1272
;      {
1273
;         png_app_error(png_ptr, "no unknown chunk support on read");
1274
;
1275
;         return;
1276
;      }
1277
;#  endif
1278
;#  if !defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED) && \
1279
;      defined(PNG_WRITE_SUPPORTED)
1280
;      if ((png_ptr->mode & PNG_IS_READ_STRUCT) == 0)
1281
;      {
1282
;         png_app_error(png_ptr, "no unknown chunk support on write");
1283
;
1284
;         return;
1285
;      }
1286
;#  endif
1287
1288
 
1289
	; unknown critical chunks could be lost with just a warning resulting in
1290
	; undefined behavior.  Now png_chunk_report is used to provide behavior
1291
	; appropriate to read or write.
1292
1293
 
1294
;       info_ptr->unknown_chunks, info_ptr->unknown_chunks_num, num_unknowns,
1295
;       sizeof *np);
1296
1297
 
1298
;   {
1299
;      png_chunk_report(png_ptr, "too many unknown chunks",
1300
;          PNG_CHUNK_WRITE_ERROR);
1301
1302
 
1303
;   }
1304
1305
 
1306
;   info_ptr->unknown_chunks = np; /* safe because it is initialized */
1307
;   info_ptr->free_me |= PNG_FREE_UNKN;
1308
1309
 
1310
1311
 
1312
	; just-allocated chunk data.
1313
1314
 
1315
;   {
1316
;      memcpy(np->name, unknowns->name, (sizeof np->name));
1317
;      np->name[(sizeof np->name)-1] = '\0';
1318
;      np->location = check_location(png_ptr, unknowns->location);
1319
1320
 
1321
;      {
1322
;         np->data = NULL;
1323
;         np->size = 0;
1324
;      }
1325
1326
 
1327
;      {
1328
;         np->data = png_malloc_base(png_ptr, unknowns->size);
1329
1330
 
1331
;         {
1332
;            png_chunk_report(png_ptr, "unknown chunk: out of memory",
1333
;                PNG_CHUNK_WRITE_ERROR);
1334
;            /* But just skip storing the unknown chunk */
1335
;            continue;
1336
;         }
1337
1338
 
1339
;         np->size = unknowns->size;
1340
;      }
1341
1342
 
1343
	; unknown chunk entry gets overwritten if the png_chunk_report returns.
1344
	; This is correct in the read case (the chunk is just dropped.)
1345
1346
 
1347
;      ++(info_ptr->unknown_chunks_num);
1348
;   }
1349
.end_f:
1350
	ret
1351
endp
1352
1353
 
1354
align 4
1355
proc png_set_unknown_chunk_location, png_ptr:dword, info_ptr:dword, chunk:dword, location:dword
1356
	; This API is pretty pointless in 1.6.0 because the location can be set
1357
	; before the call to png_set_unknown_chunks.
1358
1359
 
1360
1361
 
1362
;      chunk < info_ptr->unknown_chunks_num)
1363
;   {
1364
;      if ((location & (PNG_HAVE_IHDR|PNG_HAVE_PLTE|PNG_AFTER_IDAT)) == 0)
1365
;      {
1366
;         png_app_error(png_ptr, "invalid unknown chunk location");
1367
	; Fake out the pre 1.6.0 behavior:
1368
;         if ((location & PNG_HAVE_IDAT) != 0) /* undocumented! */
1369
;            location = PNG_AFTER_IDAT;
1370
1371
 
1372
;            location = PNG_HAVE_IHDR; /* also undocumented */
1373
;      }
1374
1375
 
1376
;         check_location(png_ptr, location);
1377
;   }
1378
	ret
1379
endp
1380
;end if /* STORE_UNKNOWN_CHUNKS */
1381
1382
 
1383
align 4
1384
proc png_permit_mng_features, png_ptr:dword, mng_features:dword
1385
	png_debug 1, 'in png_permit_mng_features'
1386
1387
 
1388
;      return 0;
1389
1390
 
1391
1392
 
1393
	ret
1394
endp
1395
1396
 
1397
;uint (bytep list, uint count, bytep add, int keep)
1398
align 4
1399
proc add_one_chunk, list:dword, count:dword, p3add:dword, keep:dword
1400
;   uint i;
1401
1402
 
1403
	; the list, otherwise add it to the list.
1404
1405
 
1406
;   {
1407
;      if (memcmp(list, p3add, 4) == 0)
1408
;      {
1409
;         list[4] = (byte)keep;
1410
1411
 
1412
;      }
1413
;   }
1414
1415
 
1416
;   {
1417
;      ++count;
1418
;      memcpy(list, p3add, 4);
1419
;      list[4] = (byte)keep;
1420
;   }
1421
1422
 
1423
	ret
1424
endp
1425
1426
 
1427
align 4
1428
proc png_set_keep_unknown_chunks uses edi, png_ptr:dword, keep:dword, chunk_list:dword, num_chunks_in:dword
1429
;   bytep new_list;
1430
;   uint num_chunks, old_num_chunks;
1431
1432
 
1433
	cmp edi,0
1434
	je .end_f ;if (..== 0) return
1435
1436
 
1437
;   {
1438
;      png_app_error(png_ptr, "png_set_keep_unknown_chunks: invalid keep");
1439
1440
 
1441
;   }
1442
1443
 
1444
;   {
1445
;      png_ptr->unknown_default = keep;
1446
1447
 
1448
;      if (num_chunks_in == 0)
1449
;        return;
1450
;   }
1451
1452
 
1453
;   {
1454
	; Ignore all unknown chunks and all chunks recognized by
1455
	; libpng except for IHDR, PLTE, tRNS, IDAT, and IEND
1456
1457
 
1458
;         98,  75,  71,  68, '\0',  /* bKGD */
1459
;         99,  72,  82,  77, '\0',  /* cHRM */
1460
;        103,  65,  77,  65, '\0',  /* gAMA */
1461
;        104,  73,  83,  84, '\0',  /* hIST */
1462
;        105,  67,  67,  80, '\0',  /* iCCP */
1463
;        105,  84,  88, 116, '\0',  /* iTXt */
1464
;        111,  70,  70, 115, '\0',  /* oFFs */
1465
;        112,  67,  65,  76, '\0',  /* pCAL */
1466
;        112,  72,  89, 115, '\0',  /* pHYs */
1467
;        115,  66,  73,  84, '\0',  /* sBIT */
1468
;        115,  67,  65,  76, '\0',  /* sCAL */
1469
;        115,  80,  76,  84, '\0',  /* sPLT */
1470
;        115,  84,  69,  82, '\0',  /* sTER */
1471
;        115,  82,  71,  66, '\0',  /* sRGB */
1472
;        116,  69,  88, 116, '\0',  /* tEXt */
1473
;        116,  73,  77,  69, '\0',  /* tIME */
1474
;        122,  84,  88, 116, '\0'   /* zTXt */
1475
;      };
1476
1477
 
1478
;      num_chunks = (uint)/*SAFE*/(sizeof chunks_to_ignore)/5U;
1479
;   }
1480
1481
 
1482
;   {
1483
;      if (chunk_list == NULL)
1484
;      {
1485
;         /* Prior to 1.6.0 this was silently ignored, now it is an app_error
1486
	; which can be switched off.
1487
1488
 
1489
1490
 
1491
;      }
1492
1493
 
1494
;   }
1495
1496
 
1497
;   if (png_ptr->chunk_list == NULL)
1498
;      old_num_chunks = 0;
1499
1500
 
1501
1502
 
1503
;   {
1504
;      png_app_error(png_ptr, "png_set_keep_unknown_chunks: too many chunks");
1505
1506
 
1507
;   }
1508
1509
 
1510
	; required because add_one_chunk above doesn't extend the list if the 'keep'
1511
	; parameter is the default.
1512
1513
 
1514
;   {
1515
;      new_list = png_malloc(png_ptr, 5 * (num_chunks + old_num_chunks));
1516
;
1517
;      if (old_num_chunks > 0)
1518
;         memcpy(new_list, png_ptr->chunk_list, 5*old_num_chunks);
1519
;   }
1520
1521
 
1522
;      new_list = png_ptr->chunk_list;
1523
1524
 
1525
;      new_list = NULL;
1526
1527
 
1528
	; already exists the code is updated, otherwise the chunk is added to the
1529
	; end.  (In libpng 1.6.0 order no longer matters because this code enforces
1530
	; the earlier convention that the last setting is the one that is used.)
1531
1532
 
1533
;   {
1534
;      bytep inlist;
1535
;      bytep outlist;
1536
;      uint i;
1537
1538
 
1539
;      {
1540
;         old_num_chunks = add_one_chunk(new_list, old_num_chunks,
1541
;             chunk_list+5*i, keep);
1542
;      }
1543
1544
 
1545
;      num_chunks = 0;
1546
;      for (i=0, inlist=outlist=new_list; i
1547
;      {
1548
;         if (inlist[4])
1549
;         {
1550
;            if (outlist != inlist)
1551
;               memcpy(outlist, inlist, 5);
1552
;            outlist += 5;
1553
;            ++num_chunks;
1554
;         }
1555
;      }
1556
1557
 
1558
;      if (num_chunks == 0)
1559
;      {
1560
;         if (png_ptr->chunk_list != new_list)
1561
;            png_free(png_ptr, new_list);
1562
;
1563
;         new_list = NULL;
1564
;      }
1565
;   }
1566
;
1567
;   else
1568
;      num_chunks = 0;
1569
;
1570
;   png_ptr->num_chunk_list = num_chunks;
1571
;
1572
;   if (png_ptr->chunk_list != new_list)
1573
;   {
1574
;      if (png_ptr->chunk_list != NULL)
1575
;         png_free(png_ptr, png_ptr->chunk_list);
1576
;
1577
;      png_ptr->chunk_list = new_list;
1578
;   }
1579
.end_f:
1580
	ret
1581
endp
1582
;end if
1583
1584
 
1585
align 4
1586
proc png_set_read_user_chunk_fn uses eax edi, png_ptr:dword, user_chunk_ptr:dword, read_user_chunk_fn:dword
1587
	png_debug 1, 'in png_set_read_user_chunk_fn'
1588
1589
 
1590
	cmp edi,0
1591
	je .end_f
1592
1593
 
1594
	mov [edi+png_struct.read_user_chunk_fn],eax
1595
	mov eax,[user_chunk_ptr]
1596
	mov [edi+png_struct.user_chunk_ptr],eax
1597
.end_f:
1598
	ret
1599
endp
1600
1601
 
1602
align 4
1603
proc png_set_rows uses eax edi esi, png_ptr:dword, info_ptr:dword, row_pointers:dword
1604
	png_debug1 1, 'in %s storage function', 'rows'
1605
1606
 
1607
	cmp edi,0
1608
	je .end_f
1609
	mov esi,[info_ptr]
1610
	cmp esi,0
1611
	je .end_f ;if (..==0 || ..==0) return
1612
1613
 
1614
	cmp dword[esi+png_info_def.row_pointers],0
1615
	je @f
1616
	cmp [esi+png_info_def.row_pointers],eax
1617
	je @f ;if (..!=0 && ..!=..)
1618
		stdcall png_free_data, edi, esi, PNG_FREE_ROWS, 0
1619
	@@:
1620
	mov [esi+png_info_def.row_pointers],eax
1621
1622
 
1623
	je .end_f ;if (..!=0)
1624
		or dword[esi+png_info_def.valid],PNG_INFO_IDAT
1625
.end_f:
1626
	ret
1627
endp
1628
1629
 
1630
align 4
1631
proc png_set_compression_buffer_size uses edi, png_ptr:dword, size:dword
1632
	mov edi,[png_ptr]
1633
	cmp edi,0
1634
	je .end_f ;if (..==0) return
1635
1636
 
1637
;      png_error(png_ptr, "invalid compression buffer size");
1638
1639
 
1640
;   if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0)
1641
;   {
1642
;      png_ptr->IDAT_read_size = (uint_32)size; /* checked above */
1643
;      return;
1644
;   }
1645
end if
1646
1647
 
1648
;   if ((png_ptr->mode & PNG_IS_READ_STRUCT) == 0)
1649
;   {
1650
;      if (png_ptr->zowner != 0)
1651
;      {
1652
;         png_warning(png_ptr,
1653
;             "Compression buffer size cannot be changed because it is in use");
1654
1655
 
1656
;      }
1657
1658
 
1659
	; Some compilers complain that this is always false.  However, it
1660
	; can be true when integer overflow happens.
1661
1662
 
1663
;      {
1664
;         png_warning(png_ptr,
1665
;             "Compression buffer size limited to system maximum");
1666
;         size = ZLIB_IO_MAX; /* must fit */
1667
;      }
1668
;end if
1669
1670
 
1671
;      {
1672
	; Deflate will potentially go into an infinite loop on a SYNC_FLUSH
1673
	; if this is permitted.
1674
1675
 
1676
;             "Compression buffer size cannot be reduced below 6");
1677
1678
 
1679
;      }
1680
1681
 
1682
;      {
1683
;         png_free_buffer_list(png_ptr, &png_ptr->zbuffer_list);
1684
;         png_ptr->zbuffer_size = (uInt)size;
1685
;      }
1686
;   }
1687
end if
1688
.end_f:
1689
	ret
1690
endp
1691
1692
 
1693
align 4
1694
proc png_set_invalid, png_ptr:dword, info_ptr:dword, mask:dword
1695
;   if (png_ptr != NULL && info_ptr != NULL)
1696
;      info_ptr->valid &= ~mask;
1697
	ret
1698
endp
1699
1700
 
1701
;void (png_structrp png_ptr, uint_32 user_width_max, uint_32 user_height_max)
1702
align 4
1703
proc png_set_user_limits uses eax edi, png_ptr:dword, user_width_max:dword, user_height_max:dword
1704
	; Images with dimensions larger than these limits will be
1705
	; rejected by png_set_IHDR().  To accept any PNG datastream
1706
	; regardless of dimensions, set both limits to 0x7fffffff.
1707
1708
 
1709
	cmp edi,0
1710
	je @f
1711
		mov eax,[user_width_max]
1712
		mov [edi+png_struct.user_width_max],eax
1713
		mov eax,[user_height_max]
1714
		mov [edi+png_struct.user_height_max],eax
1715
	@@:
1716
	ret
1717
endp
1718
1719
 
1720
;void (png_structrp png_ptr, uint_32 user_chunk_cache_max)
1721
align 4
1722
proc png_set_chunk_cache_max, png_ptr:dword, user_chunk_cache_max:dword
1723
;   if (png_ptr != NULL)
1724
;      png_ptr->user_chunk_cache_max = user_chunk_cache_max;
1725
	ret
1726
endp
1727
1728
 
1729
;void (png_structrp png_ptr, png_alloc_size_t user_chunk_malloc_max)
1730
align 4
1731
proc png_set_chunk_malloc_max, png_ptr:dword, user_chunk_malloc_max:dword
1732
;   if (png_ptr != NULL)
1733
;      png_ptr->user_chunk_malloc_max = user_chunk_malloc_max;
1734
	ret
1735
endp
1736
1737
 
1738
align 4
1739
proc png_set_benign_errors uses edi, png_ptr:dword, allowed:dword
1740
	png_debug 1, 'in png_set_benign_errors'
1741
1742
 
1743
	; If allowed is 0, png_benign_error() is treated as an error (which
1744
	; is the default behavior if png_set_benign_errors() is not called).
1745
1746
 
1747
	cmp dword[allowed],0
1748
	je @f ;if (..!=0)
1749
		or dword[edi+png_struct.flags], PNG_FLAG_BENIGN_ERRORS_WARN or PNG_FLAG_APP_WARNINGS_WARN or PNG_FLAG_APP_ERRORS_WARN
1750
		jmp .end0
1751
	@@: ;else
1752
		and dword[edi+png_struct.flags], not (PNG_FLAG_BENIGN_ERRORS_WARN or PNG_FLAG_APP_WARNINGS_WARN or PNG_FLAG_APP_ERRORS_WARN)
1753
	.end0:
1754
	ret
1755
endp
1756
1757
 
1758
; It is possible for an indexed (color-type==3) PNG file to contain
1759
; pixels with invalid (out-of-range) indexes if the PLTE chunk has
1760
; fewer entries than the image's bit-depth would allow. We recover
1761
; from this gracefully by filling any incomplete palette with zeros
1762
; (opaque black).  By default, when this occurs libpng will issue
1763
; a benign error.  This API can be used to override that behavior.
1764
1765
 
1766
align 4
1767
proc png_set_check_for_invalid_index, png_ptr:dword, allowed:dword
1768
	png_debug 1, 'in png_set_check_for_invalid_index'
1769
1770
 
1771
;      png_ptr->num_palette_max = 0;
1772
1773
 
1774
;      png_ptr->num_palette_max = -1;
1775
	ret
1776
endp
1777
1778
 
1779
; and if invalid, correct the keyword rather than discarding the entire
1780
; chunk.  The PNG 1.0 specification requires keywords 1-79 characters in
1781
; length, forbids leading or trailing whitespace, multiple internal spaces,
1782
; and the non-break space (0x80) from ISO 8859-1.  Returns keyword length.
1783
1784
 
1785
; trailing '\0').  If this routine returns 0 then there was no keyword, or a
1786
; valid one could not be generated, and the caller must png_error.
1787
1788
 
1789
align 4
1790
proc png_check_keyword, png_ptr:dword, key:dword, new_key:dword
1791
;if PNG_WARNINGS_SUPPORTED
1792
;   charp orig_key = key;
1793
;end if
1794
;   uint_32 key_len = 0;
1795
;   int bad_character = 0;
1796
;   int space = 1;
1797
1798
 
1799
1800
 
1801
;   {
1802
;      *new_key = 0;
1803
;      return 0;
1804
;   }
1805
1806
 
1807
;   {
1808
;      byte ch = (byte)*key++;
1809
1810
 
1811
;         *new_key++ = ch, ++key_len, space = 0;
1812
1813
 
1814
;      {
1815
	; A space or an invalid character when one wasn't seen immediately
1816
	; before; output just a space.
1817
1818
 
1819
1820
 
1821
;         if (ch != 32)
1822
;            bad_character = ch;
1823
;      }
1824
1825
 
1826
;         bad_character = ch; /* just skip it, record the first error */
1827
;   }
1828
1829
 
1830
;   {
1831
;      --key_len, --new_key;
1832
;      if (bad_character == 0)
1833
;         bad_character = 32;
1834
;   }
1835
1836
 
1837
;   *new_key = 0;
1838
1839
 
1840
;      return 0;
1841
1842
 
1843
	; Try to only output one warning per keyword:
1844
;   if (*key != 0) /* keyword too long */
1845
;      png_warning(png_ptr, "keyword truncated");
1846
1847
 
1848
;   {
1849
;      PNG_WARNING_PARAMETERS(p)
1850
1851
 
1852
;      png_warning_parameter_signed(p, 2, PNG_NUMBER_FORMAT_02x, bad_character);
1853
1854
 
1855
;   }
1856
end if ;!WARNINGS
1857
1858
 
1859
	ret
1860
endp
1861
>
1862