Add color pick enabled feature for product TV 74/86574/1 accepted/tizen_3.0.m2_mobile accepted/tizen_3.0.m2_tv accepted/tizen_3.0.m2_wearable accepted/tizen_3.0_common accepted/tizen_3.0_ivi accepted/tizen_3.0_mobile accepted/tizen_3.0_tv accepted/tizen_3.0_wearable accepted/tizen_common accepted/tizen_ivi accepted/tizen_mobile accepted/tizen_tv accepted/tizen_wearable tizen_3.0.m2 accepted/tizen/3.0.m2/mobile/20170105.024652 accepted/tizen/3.0.m2/tv/20170105.024836 accepted/tizen/3.0.m2/wearable/20170105.025006 accepted/tizen/3.0/common/20161114.111037 accepted/tizen/3.0/ivi/20161011.050510 accepted/tizen/3.0/mobile/20161015.033628 accepted/tizen/3.0/tv/20161016.004852 accepted/tizen/3.0/wearable/20161015.083150 accepted/tizen/common/20160907.154638 accepted/tizen/ivi/20160908.044144 accepted/tizen/mobile/20160908.043214 accepted/tizen/tv/20160908.043928 accepted/tizen/unified/20170309.035952 accepted/tizen/wearable/20160908.044035 submit/tizen/20160907.074000 submit/tizen_3.0.m2/20170104.093753 submit/tizen_3.0_common/20161104.104000 submit/tizen_3.0_ivi/20161010.000004 submit/tizen_3.0_mobile/20161015.000004 submit/tizen_3.0_tv/20161015.000003 submit/tizen_3.0_wearable/20161015.000003 submit/tizen_unified/20170308.100414
authorJiyong Min <jiyong.min@samsung.com>
Thu, 1 Sep 2016 08:02:56 +0000 (17:02 +0900)
committerJiyong Min <jiyong.min@samsung.com>
Fri, 2 Sep 2016 02:32:45 +0000 (11:32 +0900)
Change-Id: I339ca379d7b7cea44dc7dbccfa08c6254e519152
Signed-off-by: Jiyong Min <jiyong.min@samsung.com>
packaging/libpng.spec
png.h
pngread.c
pngrutil.c
scripts/symbols.def

index f8f35c3..624570d 100644 (file)
@@ -34,6 +34,13 @@ for developing programs using the PNG (Portable Network Graphics) library.
 cp %{SOURCE1001} .
 
 %build
+%ifarch %{arm}
+CFLAGS+=" -D_ARCH_ARM_ -mfpu=neon"
+%endif
+
+%if 0%{?TIZEN_PRODUCT_TV}
+CFLAGS+=" -D_PNG_COLOR_PICK_ENABLED_ -D_PNG_SEQUENTIAL_READ_SUPPORTED_"
+%endif
 
 %configure \
     --disable-static \
diff --git a/png.h b/png.h
index 123201d..f297f47 100644 (file)
--- a/png.h
+++ b/png.h
@@ -581,6 +581,32 @@ typedef struct png_text_struct
    png_charp lang_key;     /* keyword translated UTF-8 string, 0 or more
                               chars or a NULL pointer */
 } png_text;
+
+/* VD_TIZEN_ONLY */
+/* Adding PNG Color pick feature.*/
+typedef enum _Png_Color_Pick_Region_
+{
+        PNG_COLORPICK_TOP = 0,
+        PNG_COLORPICK_MIDDLE,
+        PNG_COLORPICK_BOTTOM,
+}PngColorPickRegion;
+
+struct _Png_Color_Pick_Struct_
+{
+       unsigned int sumR;
+       unsigned int sumG;
+       unsigned int sumB;
+       int enable;
+       int     perc;
+       int x1;
+       int y1;
+       int x2;
+       int y2;
+       PngColorPickRegion region;
+};
+typedef struct _Png_Color_Pick_Struct_ PngPickColor; /* TODO : PngPickColor will be changed to PngColorPick in future*/
+/* VD_TIZEN_ONLY_END */
+
 typedef png_text * png_textp;
 typedef const png_text * png_const_textp;
 typedef png_text * * png_textpp;
@@ -3106,6 +3132,13 @@ PNG_EXPORT(244, int, png_set_option, (png_structrp png_ptr, int option,
    int onoff));
 #endif /* SET_OPTION */
 
+/* VD_TIZEN_ONLY */
+/* Read the whole image into memory at once. */
+PNG_EXPORT(245, void, png_read_image_with_pick_color, (png_structp png_ptr,
+   png_bytepp image,
+   PngPickColor *pickcolor));
+/* VD_TIZEN_ONLY_END */
+
 /*******************************************************************************
  *  END OF HARDWARE AND SOFTWARE OPTIONS
  ******************************************************************************/
index dca3d7d..dfe6015 100644 (file)
--- a/pngread.c
+++ b/pngread.c
@@ -746,6 +746,130 @@ png_read_image(png_structrp png_ptr, png_bytepp image)
       }
    }
 }
+
+#ifdef _PNG_COLOR_PICK_ENABLED_
+void PNGAPI
+png_read_image_with_pick_color(png_structp png_ptr, png_bytepp image, PngPickColor *pickcolor)
+{
+   png_uint_32 i, image_height;
+   int pass, j;
+   png_uint_32 /*k = 0,*/ image_bpp = 0, image_width;
+   png_bytepp rp;
+   //png_bytep rc;
+   unsigned int npixels;
+       int perc_enable_y1, perc_enable_y2;
+   png_debug(1, "in png_read_image");
+
+   if (png_ptr == NULL || pickcolor == NULL)
+      return;
+
+#ifdef PNG_READ_INTERLACING_SUPPORTED
+   if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
+   {
+      pass = png_set_interlace_handling(png_ptr);
+      /* And make sure transforms are initialized. */
+      png_start_read_image(png_ptr);
+   }
+   else
+   {
+      if (png_ptr->interlaced && !(png_ptr->transformations & PNG_INTERLACE))
+      {
+         /* Caller called png_start_read_image or png_read_update_info without
+          * first turning on the PNG_INTERLACE transform.  We can fix this here,
+          * but the caller should do it!
+          */
+         png_warning(png_ptr, "Interlace handling should be turned on when "
+            "using png_read_image");
+         /* Make sure this is set correctly */
+         png_ptr->num_rows = png_ptr->height;
+      }
+
+      /* Obtain the pass number, which also turns on the PNG_INTERLACE flag in
+       * the above error case.
+       */
+      pass = png_set_interlace_handling(png_ptr);
+   }
+#else
+   if (png_ptr->interlaced)
+      png_error(png_ptr,
+          "Cannot read interlaced image -- interlace handler disabled");
+
+   pass = 1;
+#endif
+
+   image_height=png_ptr->height;
+   image_bpp=png_ptr->rowbytes; 
+   image_width=png_ptr->width;
+   png_ptr->user_chunk_ptr = pickcolor;
+   
+   if(pickcolor->perc < 0)
+   {
+       png_error(png_ptr, "ColorPick percentage is negative");
+       return;
+   }
+   if( (pickcolor->region < PNG_COLORPICK_TOP) || (pickcolor->region > PNG_COLORPICK_BOTTOM))
+   {
+       png_error(png_ptr, "ColorPick Region is out of bound");
+       return;
+   }
+   if(pickcolor->region == PNG_COLORPICK_TOP)
+   {
+       perc_enable_y1 = 0;
+       perc_enable_y2 = (pickcolor->perc*image_height/100) - 1;
+   }
+   else if(pickcolor->region == PNG_COLORPICK_MIDDLE)
+   {
+       perc_enable_y1 = (image_height/2) - (((pickcolor->perc/2)*image_height)/100);
+       perc_enable_y2 = perc_enable_y1 + ((pickcolor->perc*image_height)/100) - 1;
+   }
+   else
+   {
+       perc_enable_y1 = (image_height) - ( pickcolor->perc * image_height / 100  );
+       perc_enable_y2 = image_height - 1;
+   }
+
+   for (j = 0; j < pass; j++)
+   {
+      rp = image;
+      for (i = 0; i < image_height; i++)
+      {
+         pickcolor->enable = 0;
+         if( pickcolor->perc > 0 )
+         {
+            if( (int)i >= perc_enable_y1 && (int)i <= perc_enable_y2)
+            {
+               pickcolor->enable = 1;
+            }
+         }
+         else
+         {
+            if( ((int)i >= pickcolor->y1) && ((int)i <= pickcolor->y2) )
+            {
+               pickcolor->enable = 1;
+            }
+         }
+         png_read_row(png_ptr, *rp, NULL);
+         rp++;
+      }
+   }
+
+
+   if(pickcolor->perc > 0)
+   {
+      npixels = (pickcolor->perc*image_height*image_width)/100;
+   }
+   else
+   {
+      npixels = (pickcolor->x2-pickcolor->x1+1)*(pickcolor->y2-pickcolor->y1+1);
+   }
+   if(npixels > 0)
+   {
+      pickcolor->sumR = pickcolor->sumR/npixels;
+      pickcolor->sumG = pickcolor->sumG/npixels;
+      pickcolor->sumB = pickcolor->sumB/npixels;
+   }
+}
+#endif /* _PNG_COLOR_PICK_ENABLED_ */
 #endif /* SEQUENTIAL_READ */
 
 #ifdef PNG_SEQUENTIAL_READ_SUPPORTED
index c9747fc..f3eb84f 100644 (file)
@@ -14,6 +14,9 @@
  * libpng itself during the course of reading an image.
  */
 
+#ifdef _ARCH_ARM_
+#include "arm_neon.h"
+#endif
 #include "pngpriv.h"
 
 #ifdef PNG_READ_SUPPORTED
@@ -3046,6 +3049,167 @@ png_check_chunk_name(png_structrp png_ptr, png_uint_32 chunk_name)
    }
 }
 
+#ifdef _PNG_COLOR_PICK_ENABLED_
+#ifdef _ARCH_ARM_
+void 
+copy_src_to_dst(png_bytep dp, png_bytep sp, int width, 
+                  int row_stride, int nplanes, PngPickColor *png_pickcolor)
+{
+   int j;
+   unsigned char *src = (unsigned char *)sp;
+   unsigned char *dst = (unsigned char *)dp;
+
+   unsigned long long sumRGBA[4] = {0, 0, 0, 0};
+   const int const0 = 0;
+
+
+   uint32x4_t sumR_32x4 = vmovq_n_u32 ( 0 );
+   uint32x4_t sumG_32x4 = vmovq_n_u32 ( 0 );
+   uint32x4_t sumB_32x4 = vmovq_n_u32 ( 0 );
+
+   uint8x16_t R_8x16;
+   uint8x16_t G_8x16;
+   uint8x16_t B_8x16;
+
+   uint64x1x3_t sumRGB_64x1;
+
+   for(j = 0; j < width-(width&0xf); j += 16)
+   {
+      if(nplanes == 3)
+      {
+         uint8x16x3_t rgb = vld3q_u8 ( src );
+         vst3q_u8(dst, rgb);
+         R_8x16 = rgb.val[0];
+         G_8x16 = rgb.val[1];
+         B_8x16 = rgb.val[2];
+      }
+      else
+      {
+         uint8x16x4_t rgb = vld4q_u8 ( src );
+         vst4q_u8(dst, rgb);
+         R_8x16 = rgb.val[0];
+         G_8x16 = rgb.val[1];
+         B_8x16 = rgb.val[2];
+      }
+
+      if(png_pickcolor && png_pickcolor->enable)
+      {
+         if(png_pickcolor->perc > 0)
+         {
+            uint16x8_t sumR_16x8 = vpaddlq_u8 ( R_8x16 );
+            uint16x8_t sumG_16x8 = vpaddlq_u8 ( G_8x16 );
+            uint16x8_t sumB_16x8 = vpaddlq_u8 ( B_8x16 );
+
+            sumR_32x4 = vpadalq_u16 ( sumR_32x4, sumR_16x8 );
+            sumG_32x4 = vpadalq_u16 ( sumG_32x4, sumG_16x8 );
+            sumB_32x4 = vpadalq_u16 ( sumB_32x4, sumB_16x8 );
+         }
+         else if( (png_pickcolor->x1 > j) && (png_pickcolor->x1 < j + 16) )
+         {
+            int x = png_pickcolor->x1;
+            unsigned char *from = sp + (png_pickcolor->x1 * nplanes);
+            while( x < j + 16 )
+            {
+               png_pickcolor->sumR += from[0];
+               png_pickcolor->sumG += from[1];
+               png_pickcolor->sumB += from[2];
+               from += nplanes;
+               x ++;
+            }
+         }
+         else if( (png_pickcolor->x2 >= j) && (png_pickcolor->x2 < j + 16) )
+         {
+            int x = j;
+            unsigned char *from = sp + (j * nplanes);
+            while(x <= png_pickcolor->x2)
+            {
+               png_pickcolor->sumR += from[0];
+               png_pickcolor->sumG += from[1];
+               png_pickcolor->sumB += from[2];
+               from += nplanes;
+               x ++;
+            }
+         }
+         else if ( (j >= png_pickcolor->x1) && (j+15 <= png_pickcolor->x2) )
+         {
+            uint16x8_t sumR_16x8 = vpaddlq_u8 ( R_8x16 );
+            uint16x8_t sumG_16x8 = vpaddlq_u8 ( G_8x16 );
+            uint16x8_t sumB_16x8 = vpaddlq_u8 ( B_8x16 );
+
+            sumR_32x4 = vpadalq_u16 ( sumR_32x4, sumR_16x8 );
+            sumG_32x4 = vpadalq_u16 ( sumG_32x4, sumG_16x8 );
+            sumB_32x4 = vpadalq_u16 ( sumB_32x4, sumB_16x8 );
+         }
+      }
+      dst += (nplanes*16);
+      src += (nplanes*16);
+   }
+
+   if(png_pickcolor && png_pickcolor->enable)
+   {
+
+      uint64x2_t sumR_64x2 = vpaddlq_u32 ( sumR_32x4 );
+      uint64x2_t sumG_64x2 = vpaddlq_u32 ( sumG_32x4 );
+      uint64x2_t sumB_64x2 = vpaddlq_u32 ( sumB_32x4 );        
+
+      uint64x1_t sumR_Lo_64x1 = vget_low_u64 ( sumR_64x2 );
+      uint64x1_t sumR_Hi_64x1 = vget_high_u64 ( sumR_64x2 );
+
+      uint64x1_t sumG_Lo_64x1 = vget_low_u64 ( sumG_64x2 );
+      uint64x1_t sumG_Hi_64x1 = vget_high_u64 ( sumG_64x2 );
+
+      uint64x1_t sumB_Lo_64x1 = vget_low_u64 ( sumB_64x2 );
+      uint64x1_t sumB_Hi_64x1 = vget_high_u64 ( sumB_64x2 );
+
+      sumRGB_64x1.val[0] = vadd_u64 ( sumR_Lo_64x1, sumR_Hi_64x1 );
+      sumRGB_64x1.val[1] = vadd_u64 ( sumG_Lo_64x1, sumG_Hi_64x1 );
+      sumRGB_64x1.val[2] = vadd_u64 ( sumB_Lo_64x1, sumB_Hi_64x1 );
+
+      vst3_u64( sumRGBA, sumRGB_64x1);
+
+      png_pickcolor->sumR += sumRGBA[0];
+      png_pickcolor->sumG += sumRGBA[1];       
+      png_pickcolor->sumB += sumRGBA[2];       
+   }
+
+   memcpy(dst, src, (width-j)*nplanes);
+   if(png_pickcolor && png_pickcolor->enable)
+   {
+      if(png_pickcolor->perc <= 0)
+      {
+         if(j < png_pickcolor->x1)
+         {
+            j = png_pickcolor->x1;
+            dst = dp + (j*nplanes);
+         }
+         width = png_pickcolor->x2;
+      }
+      for(; j < width ; j ++)
+      {
+         png_pickcolor->sumR += dst[0];
+         png_pickcolor->sumG += dst[1];
+         png_pickcolor->sumB += dst[2];
+         dst += nplanes;
+      }
+   }
+}
+
+void copy_row(png_bytep dp, png_bytep sp, int width, int pixel_bits, PngPickColor *png_pickcolor)
+{
+   int row_stride = PNG_ROWBYTES(pixel_bits, width);
+   if(pixel_bits == 24 || pixel_bits == 32)
+   {
+      copy_src_to_dst(dp, sp, width, row_stride, pixel_bits >> 3, png_pickcolor);
+   }
+   else
+   {
+      memcpy(dp, sp, row_stride);
+   }
+
+}
+#endif
+#endif
+
 /* Combines the row recently read in with the existing pixels in the row.  This
  * routine takes care of alpha and transparency if requested.  This routine also
  * handles the two methods of progressive display of interlaced images,
index 4c35fd7..4df4a4f 100644 (file)
@@ -249,3 +249,4 @@ EXPORTS
  png_set_check_for_invalid_index @242
  png_get_palette_max @243
  png_set_option @244
+ png_read_image_with_pick_color @245