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. ; pngwtran.asm - transforms the data in a row for PNG writers
  3.  
  4. ; Last changed in libpng 1.6.24 [August 4, 2016]
  5. ; Copyright (c) 1998-2002,2004,2006-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.  
  14. ; Pack pixels into bytes.  Pass the true bit depth in bit_depth.  The
  15. ; row_info bit depth should be 8 (one pixel per byte).  The channels
  16. ; should be 1 (this only happens on grayscale and paletted images).
  17.  
  18. ;void (png_row_infop row_info, bytep row, uint_32 bit_depth)
  19. align 4
  20. proc png_do_pack, row_info:dword, row:dword, bit_depth:dword
  21.         png_debug 1, 'in png_do_pack'
  22.  
  23. ;   if (row_info->bit_depth == 8 &&
  24. ;      row_info->channels == 1)
  25. ;   {
  26. ;      switch ((int)bit_depth)
  27. ;      {
  28. ;         case 1:
  29. ;         {
  30. ;            bytep sp, dp;
  31. ;            int mask, v;
  32. ;            uint_32 i;
  33. ;            uint_32 row_width = row_info->width;
  34.  
  35. ;            sp = row;
  36. ;            dp = row;
  37. ;            mask = 0x80;
  38. ;            v = 0;
  39.  
  40. ;            for (i = 0; i < row_width; i++)
  41. ;            {
  42. ;               if (*sp != 0)
  43. ;                  v |= mask;
  44.  
  45. ;               sp++;
  46.  
  47. ;               if (mask > 1)
  48. ;                  mask >>= 1;
  49.  
  50. ;               else
  51. ;               {
  52. ;                  mask = 0x80;
  53. ;                  *dp = (byte)v;
  54. ;                  dp++;
  55. ;                  v = 0;
  56. ;               }
  57. ;            }
  58.  
  59. ;            if (mask != 0x80)
  60. ;               *dp = (byte)v;
  61.  
  62. ;            break;
  63. ;         }
  64.  
  65. ;         case 2:
  66. ;         {
  67. ;            bytep sp, dp;
  68. ;            unsigned int shift;
  69. ;            int v;
  70. ;            uint_32 i;
  71. ;            uint_32 row_width = row_info->width;
  72.  
  73. ;            sp = row;
  74. ;            dp = row;
  75. ;            shift = 6;
  76. ;            v = 0;
  77.  
  78. ;            for (i = 0; i < row_width; i++)
  79. ;            {
  80. ;               byte value;
  81.  
  82. ;               value = (byte)(*sp & 0x03);
  83. ;               v |= (value << shift);
  84.  
  85. ;               if (shift == 0)
  86. ;               {
  87. ;                  shift = 6;
  88. ;                  *dp = (byte)v;
  89. ;                  dp++;
  90. ;                  v = 0;
  91. ;               }
  92.  
  93. ;               else
  94. ;                  shift -= 2;
  95. ;
  96. ;               sp++;
  97. ;            }
  98.  
  99. ;            if (shift != 6)
  100. ;               *dp = (byte)v;
  101.  
  102. ;            break;
  103. ;         }
  104.  
  105. ;         case 4:
  106. ;         {
  107. ;            bytep sp, dp;
  108. ;            unsigned int shift;
  109. ;            int v;
  110. ;            uint_32 i;
  111. ;            uint_32 row_width = row_info->width;
  112.  
  113. ;            sp = row;
  114. ;            dp = row;
  115. ;            shift = 4;
  116. ;            v = 0;
  117.  
  118. ;            for (i = 0; i < row_width; i++)
  119. ;            {
  120. ;               byte value;
  121.  
  122. ;               value = (byte)(*sp & 0x0f);
  123. ;               v |= (value << shift);
  124.  
  125. ;               if (shift == 0)
  126. ;               {
  127. ;                  shift = 4;
  128. ;                  *dp = (byte)v;
  129. ;                  dp++;
  130. ;                  v = 0;
  131. ;               }
  132.  
  133. ;               else
  134. ;                  shift -= 4;
  135. ;
  136. ;               sp++;
  137. ;            }
  138.  
  139. ;            if (shift != 4)
  140. ;               *dp = (byte)v;
  141.  
  142. ;            break;
  143. ;         }
  144.  
  145. ;         default:
  146. ;            break;
  147. ;      }
  148.  
  149. ;      row_info->bit_depth = (byte)bit_depth;
  150. ;      row_info->pixel_depth = (byte)(bit_depth * row_info->channels);
  151. ;      row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,
  152. ;          row_info->width);
  153. ;   }
  154.         ret
  155. endp
  156.  
  157. ; Shift pixel values to take advantage of whole range.  Pass the
  158. ; true number of bits in bit_depth.  The row should be packed
  159. ; according to row_info->bit_depth.  Thus, if you had a row of
  160. ; bit depth 4, but the pixels only had values from 0 to 7, you
  161. ; would pass 3 as bit_depth, and this routine would translate the
  162. ; data to 0 to 15.
  163.  
  164. ;void (png_row_infop row_info, bytep row, png_const_color_8p bit_depth)
  165. align 4
  166. proc png_do_shift, row_info:dword, row:dword, bit_depth:dword
  167.         png_debug 1, 'in png_do_shift'
  168.  
  169. ;   if (row_info->color_type != PNG_COLOR_TYPE_PALETTE)
  170. ;   {
  171. ;      int shift_start[4], shift_dec[4];
  172. ;      int channels = 0;
  173.  
  174. ;      if ((row_info->color_type & PNG_COLOR_MASK_COLOR) != 0)
  175. ;      {
  176. ;         shift_start[channels] = row_info->bit_depth - bit_depth->red;
  177. ;         shift_dec[channels] = bit_depth->red;
  178. ;         channels++;
  179.  
  180. ;         shift_start[channels] = row_info->bit_depth - bit_depth->green;
  181. ;         shift_dec[channels] = bit_depth->green;
  182. ;         channels++;
  183.  
  184. ;         shift_start[channels] = row_info->bit_depth - bit_depth->blue;
  185. ;         shift_dec[channels] = bit_depth->blue;
  186. ;         channels++;
  187. ;      }
  188.  
  189. ;      else
  190. ;      {
  191. ;         shift_start[channels] = row_info->bit_depth - bit_depth->gray;
  192. ;         shift_dec[channels] = bit_depth->gray;
  193. ;         channels++;
  194. ;      }
  195.  
  196. ;      if ((row_info->color_type & PNG_COLOR_MASK_ALPHA) != 0)
  197. ;      {
  198. ;         shift_start[channels] = row_info->bit_depth - bit_depth->alpha;
  199. ;         shift_dec[channels] = bit_depth->alpha;
  200. ;         channels++;
  201. ;      }
  202.  
  203.         ; With low row depths, could only be grayscale, so one channel
  204. ;      if (row_info->bit_depth < 8)
  205. ;      {
  206. ;         bytep bp = row;
  207. ;         png_size_t i;
  208. ;         unsigned int mask;
  209. ;         png_size_t row_bytes = row_info->rowbytes;
  210.  
  211. ;         if (bit_depth->gray == 1 && row_info->bit_depth == 2)
  212. ;            mask = 0x55;
  213.  
  214. ;         else if (row_info->bit_depth == 4 && bit_depth->gray == 3)
  215. ;            mask = 0x11;
  216.  
  217. ;         else
  218. ;            mask = 0xff;
  219.  
  220. ;         for (i = 0; i < row_bytes; i++, bp++)
  221. ;         {
  222. ;            int j;
  223. ;            unsigned int v, out;
  224.  
  225. ;            v = *bp;
  226. ;            out = 0;
  227.  
  228. ;            for (j = shift_start[0]; j > -shift_dec[0]; j -= shift_dec[0])
  229. ;            {
  230. ;               if (j > 0)
  231. ;                  out |= v << j;
  232.  
  233. ;               else
  234. ;                  out |= (v >> (-j)) & mask;
  235. ;            }
  236.  
  237. ;            *bp = (byte)(out & 0xff);
  238. ;         }
  239. ;      }
  240.  
  241. ;      else if (row_info->bit_depth == 8)
  242. ;      {
  243. ;         bytep bp = row;
  244. ;         uint_32 i;
  245. ;         uint_32 istop = channels * row_info->width;
  246.  
  247. ;         for (i = 0; i < istop; i++, bp++)
  248. ;         {
  249.  
  250. ;            const unsigned int c = i%channels;
  251. ;            int j;
  252. ;            unsigned int v, out;
  253.  
  254. ;            v = *bp;
  255. ;            out = 0;
  256.  
  257. ;            for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c])
  258. ;            {
  259. ;               if (j > 0)
  260. ;                  out |= v << j;
  261.  
  262. ;               else
  263. ;                  out |= v >> (-j);
  264. ;            }
  265.  
  266. ;            *bp = (byte)(out & 0xff);
  267. ;         }
  268. ;      }
  269.  
  270. ;      else
  271. ;      {
  272. ;         bytep bp;
  273. ;         uint_32 i;
  274. ;         uint_32 istop = channels * row_info->width;
  275.  
  276. ;         for (bp = row, i = 0; i < istop; i++)
  277. ;         {
  278. ;            const unsigned int c = i%channels;
  279. ;            int j;
  280. ;            unsigned int value, v;
  281.  
  282. ;            v = png_get_uint_16(bp);
  283. ;            value = 0;
  284.  
  285. ;            for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c])
  286. ;            {
  287. ;               if (j > 0)
  288. ;                  value |= v << j;
  289.  
  290. ;               else
  291. ;                  value |= v >> (-j);
  292. ;            }
  293. ;            *bp++ = (byte)((value >> 8) & 0xff);
  294. ;            *bp++ = (byte)(value & 0xff);
  295. ;         }
  296. ;      }
  297. ;   }
  298.         ret
  299. endp
  300.  
  301. ;void (png_row_infop row_info, bytep row)
  302. align 4
  303. proc png_do_write_swap_alpha, row_info:dword, row:dword
  304.         png_debug 1, 'in png_do_write_swap_alpha'
  305.  
  306. ;   {
  307. ;      if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
  308. ;      {
  309. ;         if (row_info->bit_depth == 8)
  310. ;         {
  311.                 ; This converts from ARGB to RGBA
  312. ;            bytep sp, dp;
  313. ;            uint_32 i;
  314. ;            uint_32 row_width = row_info->width;
  315.  
  316. ;            for (i = 0, sp = dp = row; i < row_width; i++)
  317. ;            {
  318. ;               byte save = *(sp++);
  319. ;               *(dp++) = *(sp++);
  320. ;               *(dp++) = *(sp++);
  321. ;               *(dp++) = *(sp++);
  322. ;               *(dp++) = save;
  323. ;            }
  324. ;         }
  325.  
  326. if PNG_WRITE_16BIT_SUPPORTED eq 1
  327. ;         else
  328. ;         {
  329.                 ; This converts from AARRGGBB to RRGGBBAA
  330. ;            bytep sp, dp;
  331. ;            uint_32 i;
  332. ;            uint_32 row_width = row_info->width;
  333. ;
  334. ;            for (i = 0, sp = dp = row; i < row_width; i++)
  335. ;            {
  336. ;               byte save[2];
  337. ;               save[0] = *(sp++);
  338. ;               save[1] = *(sp++);
  339. ;               *(dp++) = *(sp++);
  340. ;               *(dp++) = *(sp++);
  341. ;               *(dp++) = *(sp++);
  342. ;               *(dp++) = *(sp++);
  343. ;               *(dp++) = *(sp++);
  344. ;               *(dp++) = *(sp++);
  345. ;               *(dp++) = save[0];
  346. ;               *(dp++) = save[1];
  347. ;            }
  348. ;         }
  349. end if ;WRITE_16BIT
  350. ;      }
  351. ;
  352. ;      else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
  353. ;      {
  354. ;         if (row_info->bit_depth == 8)
  355. ;         {
  356.                 ; This converts from AG to GA
  357. ;            bytep sp, dp;
  358. ;            uint_32 i;
  359. ;            uint_32 row_width = row_info->width;
  360.  
  361. ;            for (i = 0, sp = dp = row; i < row_width; i++)
  362. ;            {
  363. ;               byte save = *(sp++);
  364. ;               *(dp++) = *(sp++);
  365. ;               *(dp++) = save;
  366. ;            }
  367. ;         }
  368.  
  369. if PNG_WRITE_16BIT_SUPPORTED eq 1
  370. ;         else
  371. ;         {
  372.         ; This converts from AAGG to GGAA
  373. ;            bytep sp, dp;
  374. ;            uint_32 i;
  375. ;            uint_32 row_width = row_info->width;
  376.  
  377. ;            for (i = 0, sp = dp = row; i < row_width; i++)
  378. ;            {
  379. ;               byte save[2];
  380. ;               save[0] = *(sp++);
  381. ;               save[1] = *(sp++);
  382. ;               *(dp++) = *(sp++);
  383. ;               *(dp++) = *(sp++);
  384. ;               *(dp++) = save[0];
  385. ;               *(dp++) = save[1];
  386. ;            }
  387. ;         }
  388. end if ;WRITE_16BIT
  389. ;      }
  390. ;   }
  391.         ret
  392. endp
  393.  
  394. ;void (png_row_infop row_info, bytep row)
  395. align 4
  396. proc png_do_write_invert_alpha, row_info:dword, row:dword
  397.         png_debug 1, 'in png_do_write_invert_alpha'
  398.  
  399. ;      if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
  400. ;      {
  401. ;         if (row_info->bit_depth == 8)
  402. ;         {
  403.         ; This inverts the alpha channel in RGBA
  404. ;            bytep sp, dp;
  405. ;            uint_32 i;
  406. ;            uint_32 row_width = row_info->width;
  407.  
  408. ;            for (i = 0, sp = dp = row; i < row_width; i++)
  409. ;            {
  410.         ; Does nothing
  411.         ;*(dp++) = *(sp++);
  412.         ;*(dp++) = *(sp++);
  413.         ;*(dp++) = *(sp++);
  414.  
  415. ;               sp+=3; dp = sp;
  416. ;               *dp = (byte)(255 - *(sp++));
  417. ;            }
  418. ;         }
  419.  
  420. ;if PNG_WRITE_16BIT_SUPPORTED
  421. ;         else
  422. ;         {
  423.                 ; This inverts the alpha channel in RRGGBBAA
  424. ;            bytep sp, dp;
  425. ;            uint_32 i;
  426. ;            uint_32 row_width = row_info->width;
  427.  
  428. ;            for (i = 0, sp = dp = row; i < row_width; i++)
  429. ;            {
  430.         ; Does nothing
  431.         ;*(dp++) = *(sp++);
  432.         ;*(dp++) = *(sp++);
  433.         ;*(dp++) = *(sp++);
  434.         ;*(dp++) = *(sp++);
  435.         ;*(dp++) = *(sp++);
  436.         ;*(dp++) = *(sp++);
  437.  
  438. ;               sp+=6; dp = sp;
  439. ;               *(dp++) = (byte)(255 - *(sp++));
  440. ;               *dp     = (byte)(255 - *(sp++));
  441. ;            }
  442. ;         }
  443. ;end if /* WRITE_16BIT */
  444. ;      }
  445.  
  446. ;      else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
  447. ;      {
  448. ;         if (row_info->bit_depth == 8)
  449. ;         {
  450.                 ; This inverts the alpha channel in GA
  451. ;            bytep sp, dp;
  452. ;            uint_32 i;
  453. ;            uint_32 row_width = row_info->width;
  454. ;
  455. ;            for (i = 0, sp = dp = row; i < row_width; i++)
  456. ;            {
  457. ;               *(dp++) = *(sp++);
  458. ;               *(dp++) = (byte)(255 - *(sp++));
  459. ;            }
  460. ;         }
  461.  
  462. if PNG_WRITE_16BIT_SUPPORTED eq 1
  463. ;         else
  464. ;         {
  465.         ; This inverts the alpha channel in GGAA
  466. ;            bytep sp, dp;
  467. ;            uint_32 i;
  468. ;            uint_32 row_width = row_info->width;
  469. ;
  470. ;            for (i = 0, sp = dp = row; i < row_width; i++)
  471. ;            {
  472.         ; Does nothing
  473.         ;*(dp++) = *(sp++);
  474.         ;*(dp++) = *(sp++);
  475.  
  476. ;               sp+=2; dp = sp;
  477. ;               *(dp++) = (byte)(255 - *(sp++));
  478. ;               *dp     = (byte)(255 - *(sp++));
  479. ;            }
  480. ;         }
  481. end if ;WRITE_16BIT
  482. ;      }
  483.         ret
  484. endp
  485.  
  486. ; Transform the data according to the user's wishes.  The order of
  487. ; transformations is significant.
  488.  
  489. ;void (png_structrp png_ptr, png_row_infop row_info)
  490. align 4
  491. proc png_do_write_transformations uses eax ebx edi esi, png_ptr:dword, row_info:dword
  492.         png_debug 1, 'in png_do_write_transformations'
  493.  
  494.         mov edi,[png_ptr]
  495.         cmp edi,0
  496.         je .end_f ;if (..==0) return
  497.         mov esi,[row_info]
  498.         mov ebx,[edi+png_struct.row_buf]
  499.         inc ebx ;start of pixel data for row
  500.  
  501. if PNG_WRITE_USER_TRANSFORM_SUPPORTED eq 1
  502.         mov eax,[edi+png_struct.transformations]
  503.         and eax,PNG_USER_TRANSFORM
  504.         cmp eax,0
  505.         je @f ;if (..!=0)
  506.         mov eax,[edi+png_struct.write_user_transform_fn]
  507.         cmp eax,0
  508.         je @f ;if (..!=0)
  509.                 stdcall eax, edi, esi, ebx ;User write transform function
  510.                 ; row_info:
  511.                 ;  uint_32 width    ;width of row
  512.                 ;  png_size_t rowbytes ;number of bytes in row
  513.                 ;  byte  color_type ;color type of pixels
  514.                 ;  byte  bit_depth  ;bit depth of samples
  515.                 ;  byte  channels   ;number of channels (1-4)
  516.                 ;  byte  pixel_depth ;bits per pixel (depth*channels)
  517.         @@:
  518. end if
  519.  
  520. if PNG_WRITE_FILLER_SUPPORTED eq 1
  521.         mov eax,[edi+png_struct.transformations]
  522.         and eax,PNG_FILLER
  523.         cmp eax,0
  524.         je @f ;if (..!=0)
  525.                 mov eax,[edi+png_struct.flags]
  526.                 and eax,PNG_FLAG_FILLER_AFTER
  527.                 not eax
  528.                 stdcall png_do_strip_channel, esi, ebx, eax
  529.         @@:
  530. end if
  531.  
  532. if PNG_WRITE_PACKSWAP_SUPPORTED eq 1
  533.         mov eax,[edi+png_struct.transformations]
  534.         and eax,PNG_PACKSWAP
  535.         cmp eax,0
  536.         je @f ;if (..!=0)
  537.                 stdcall png_do_packswap, esi, ebx
  538.         @@:
  539. end if
  540.  
  541. if PNG_WRITE_PACK_SUPPORTED eq 1
  542.         mov eax,[edi+png_struct.transformations]
  543.         and eax,PNG_PACK
  544.         cmp eax,0
  545.         je @f ;if (..!=0)
  546.                 movzx eax,byte[edi+png_struct.bit_depth]
  547.                 stdcall png_do_pack, esi, ebx, eax
  548.         @@:
  549. end if
  550.  
  551. if PNG_WRITE_SWAP_SUPPORTED eq 1
  552. if PNG_16BIT_SUPPORTED eq 1
  553.         mov eax,[edi+png_struct.transformations]
  554.         and eax,PNG_SWAP_BYTES
  555.         cmp eax,0
  556.         je @f ;if (..!=0)
  557.                 stdcall png_do_swap, esi, ebx
  558.         @@:
  559. end if
  560. end if
  561.  
  562. if PNG_WRITE_SHIFT_SUPPORTED eq 1
  563.         mov eax,[edi+png_struct.transformations]
  564.         and eax,PNG_SHIFT
  565.         cmp eax,0
  566.         je @f ;if (..!=0)
  567.                 mov eax,edi
  568.                 add eax,png_struct.shift
  569.                 stdcall png_do_shift, esi, ebx, eax
  570.         @@:
  571. end if
  572.  
  573. if PNG_WRITE_SWAP_ALPHA_SUPPORTED eq 1
  574.         mov eax,[edi+png_struct.transformations]
  575.         and eax,PNG_SWAP_ALPHA
  576.         cmp eax,0
  577.         je @f ;if (..!=0)
  578.                 stdcall png_do_write_swap_alpha, esi, ebx
  579.         @@:
  580. end if
  581.  
  582. if PNG_WRITE_INVERT_ALPHA_SUPPORTED eq 1
  583.         mov eax,[edi+png_struct.transformations]
  584.         and eax,PNG_INVERT_ALPHA
  585.         cmp eax,0
  586.         je @f ;if (..!=0)
  587.                 stdcall png_do_write_invert_alpha, esi, ebx
  588.         @@:
  589. end if
  590.  
  591. if PNG_WRITE_BGR_SUPPORTED eq 1
  592.         mov eax,[edi+png_struct.transformations]
  593.         and eax,PNG_BGR
  594.         cmp eax,0
  595.         je @f ;if (..!=0)
  596.                 stdcall png_do_bgr, esi, ebx
  597.         @@:
  598. end if
  599.  
  600. if PNG_WRITE_INVERT_SUPPORTED eq 1
  601.         mov eax,[edi+png_struct.transformations]
  602.         and eax,PNG_INVERT_MONO
  603.         cmp eax,0
  604.         je @f ;if (..!=0)
  605.                 stdcall png_do_invert, esi, ebx
  606.         @@:
  607. end if
  608. .end_f:
  609.         ret
  610. endp
  611.