cedric pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=2fd69743f968aa7a184edf183384e5a359e79c8f

commit 2fd69743f968aa7a184edf183384e5a359e79c8f
Author: Cedric BAIL <cedric.b...@samsung.com>
Date:   Mon Mar 24 19:55:45 2014 +0900

    evas: change TGV internal encoding to account for GPU needs of duplicated 
border.
    
    With OpenGL, the border of a texture are not "well" defined. So 
interpolation at
    the border can result in weird/bad looking texture border. To avoid that we 
do
    duplicate the border in all direction at the time of the texture upload. 
But with
    ETC1 it is not possible as the border are grouped with 15 others pixels. It 
needs
    to be done at saving time. So internally we do have an image that would be 
of
    size width + 2 pixels and height + 2 pixels.
---
 src/modules/evas/savers/tgv/evas_image_save_tgv.c | 156 ++++++++++++++--------
 1 file changed, 99 insertions(+), 57 deletions(-)

diff --git a/src/modules/evas/savers/tgv/evas_image_save_tgv.c 
b/src/modules/evas/savers/tgv/evas_image_save_tgv.c
index 5ccbed4..c344df0 100644
--- a/src/modules/evas/savers/tgv/evas_image_save_tgv.c
+++ b/src/modules/evas/savers/tgv/evas_image_save_tgv.c
@@ -28,6 +28,7 @@ evas_image_save_file_tgv(RGBA_Image *im,
    unsigned int x, y;
    unsigned int compress_length;
    unsigned int block_count;
+   unsigned int real_x, real_y;
 
    if (!im || !im->image.data || !file)
      return 0;
@@ -86,63 +87,104 @@ evas_image_save_file_tgv(RGBA_Image *im,
      }
 
    // Write block
-   for (y = 0; y < im->cache_entry.h; y += block)
-     for (x = 0; x < im->cache_entry.w; x += block)
-       {
-          unsigned int i, j;
-          int wlen;
-          char *offset = buffer;
-
-          for (i = 0; i < block; i += 4)
-            for (j = 0; j < block; j += 4)
-              {
-                 unsigned char todo[64] = { 0 };
-                 int k, kmax, lmax;
-
-                 kmax = y + i + 4 < im->cache_entry.h ?
-                   4 : im->cache_entry.h - y - i - 1;
-                 lmax = x + j + 4 < im->cache_entry.w ?
-                   4 : im->cache_entry.w - x - j - 1;
-
-                 if (lmax > 0)
-                   {
-                      for (k = 0; k < kmax; k++)
-                        memcpy(&todo[k * 16],
-                               &data[(y + i + k) * im->cache_entry.w + x + j],
-                               4 * lmax);
-                   }
-
-                 rg_etc1_pack_block(offset, (unsigned int*) todo, &param);
-                 offset += 8;
-              }
-
-          if (compress)
-            {
-               wlen = LZ4_compress(buffer, comp, block_count * 8);
-            }
-          else
-            {
-               comp = buffer;
-               wlen = block_count * 8;
-            }
-
-          if (wlen > 0)
-            {
-               unsigned int blen = wlen;
-
-               while (blen)
-                 {
-                    unsigned char plen;
-
-                    plen = blen & 0x7F;
-                    blen = blen >> 7;
-
-                    if (blen) plen = 0x80 | plen;
-                    fwrite(&plen, 1, 1, f);
-                 }
-               fwrite(comp, wlen, 1, f);
-            }
-       }
+   for (y = 0; y < im->cache_entry.h + 2; y += block)
+     {
+        real_y = y > 0 ? y - 1 : 0;
+
+        for (x = 0; x < im->cache_entry.w + 2; x += block)
+          {
+             unsigned int i, j;
+             unsigned char duplicate_w[2], duplicate_h[2];
+             int wlen;
+             char *offset = buffer;
+
+             real_x = x > 0 ? x - 1 : 0;
+
+             for (i = 0; i < block; i += 4)
+               {
+                  unsigned char block_h;
+                  int kmax;
+
+                  duplicate_h[0] = !!((real_y + i) == 0);
+                  duplicate_h[1] = !!((real_y + i + (4 - duplicate_h[0])) >= 
im->cache_entry.h);
+                  block_h = 4 - duplicate_h[0] - duplicate_h[1];
+
+                  kmax = real_y + i + block_h < im->cache_entry.h ?
+                    block_h : im->cache_entry.h - real_y - i - 1;
+
+                  for (j = 0; j < block; j += 4)
+                    {
+                       unsigned char todo[64] = { 0 };
+                       unsigned char block_w;
+                       int block_length;
+                       int k, lmax;
+
+                       duplicate_w[0] = !!((real_x + j) == 0);
+                       duplicate_w[1] = !!(((real_x + j + (4 - 
duplicate_w[0]))) >= im->cache_entry.w);
+                       block_w = 4 - duplicate_w[0] - duplicate_w[1];
+
+                       lmax = real_x + j + block_w < im->cache_entry.w ?
+                         block_w : im->cache_entry.w - real_x - j - 1;
+                       block_length = real_x + j + 4 < im->cache_entry.w ?
+                         4 : im->cache_entry.w - real_x - j - 1;
+
+                       if (lmax > 0)
+                         {
+                            for (k = duplicate_h[0]; k < kmax; k++)
+                              memcpy(&todo[k * 16 + duplicate_w[0] * 4],
+                                     &data[(real_y + i + k) * 
im->cache_entry.w + real_x + j],
+                                     4 * lmax);
+                         }
+
+                       if (duplicate_h[0] && block_length > 0) // Duplicate 
first line
+                         memcpy(&todo[0], &data[(real_y + i) * 
im->cache_entry.w + real_x + j], block_length);
+                       if (duplicate_h[1] && block_length > 0 && kmax > 0) // 
Duplicate last line
+                         memcpy(&todo[kmax * 16], &data[(real_y + i + kmax) * 
im->cache_entry.w + real_x + j], block_length);
+                       if (duplicate_w[0]) // Duplicate first row
+                         {
+                            for (k = 0; k < kmax; k++)
+                              memcpy(&todo[k * 16], &data[(real_y + i + k) * 
im->cache_entry.w + real_x + j], 4); // Copy a pixel at a time
+                         }
+                       if (duplicate_w[1] && lmax >= 0) // Duplicate last row
+                         {
+                            for (k = 0; k < kmax; k++)
+                              memcpy(&todo[k * 16 + (duplicate_w[0] + lmax) * 
4],
+                                     &data[(real_y + i + k) * 
im->cache_entry.w + real_x + j + lmax], 4); // Copy a pixel at a time
+                         }
+
+                       rg_etc1_pack_block(offset, (unsigned int*) todo, 
&param);
+                       offset += 8;
+                    }
+               }
+
+             if (compress)
+               {
+                  wlen = LZ4_compress(buffer, comp, block_count * 8);
+               }
+             else
+               {
+                  comp = buffer;
+                  wlen = block_count * 8;
+               }
+
+             if (wlen > 0)
+               {
+                  unsigned int blen = wlen;
+
+                  while (blen)
+                    {
+                       unsigned char plen;
+
+                       plen = blen & 0x7F;
+                       blen = blen >> 7;
+
+                       if (blen) plen = 0x80 | plen;
+                       fwrite(&plen, 1, 1, f);
+                    }
+                  fwrite(comp, wlen, 1, f);
+               }
+          }
+     }
    fclose(f);
 
    return 1;

-- 


Reply via email to