Subversion Repositories Kolibri OS

Rev

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

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