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;
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
******************************************************************************/
}
}
}
+
+#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
* libpng itself during the course of reading an image.
*/
+#ifdef _ARCH_ARM_
+#include "arm_neon.h"
+#endif
#include "pngpriv.h"
#ifdef PNG_READ_SUPPORTED
}
}
+#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,