Add pkg config and color picker feature for product TV 77/86777/5 accepted/tizen_3.0.m2_mobile accepted/tizen_3.0.m2_tv accepted/tizen_3.0.m2_wearable tizen_3.0.m2 tizen_3.0_tv accepted/tizen/3.0.m2/mobile/20170105.024740 accepted/tizen/3.0.m2/tv/20170105.024917 accepted/tizen/3.0.m2/wearable/20170105.025043 accepted/tizen/3.0/common/20161114.111005 accepted/tizen/3.0/ivi/20161011.044340 accepted/tizen/3.0/mobile/20161015.033517 accepted/tizen/3.0/tv/20161016.005013 accepted/tizen/3.0/wearable/20161015.083238 accepted/tizen/common/20160912.175314 accepted/tizen/ivi/20160912.093129 accepted/tizen/mobile/20160912.093032 accepted/tizen/tv/20160912.093049 accepted/tizen/unified/20170309.040112 accepted/tizen/wearable/20160912.093109 submit/tizen/20160911.221659 submit/tizen_3.0.m2/20170104.093753 submit/tizen_3.0_common/20161104.104000 submit/tizen_3.0_ivi/20161010.000003 submit/tizen_3.0_mobile/20161015.000003 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>
Mon, 5 Sep 2016 00:15:19 +0000 (09:15 +0900)
committerJiyong Min <jiyong.min@samsung.com>
Tue, 6 Sep 2016 06:36:16 +0000 (15:36 +0900)
Change-Id: I7c28cda7b8727039c9eb5af8aee6d3e6ef8c1a8b
Signed-off-by: Jiyong Min <jiyong.min@samsung.com>
19 files changed:
Makefile.am
bmp.c
configure.ac
jconfig.h.in
jdcoefct.c
jdmarker.c
jdmerge.c
jpeglib.h
jquant2.c
md5/md5hl.c
packaging/libjpeg-turbo.spec
pkgconfig/Makefile.am [new file with mode: 0755]
pkgconfig/turbojpeg.pc.in [new file with mode: 0755]
rdppm.c
simd/jsimd.h
simd/jsimd_arm.c
simd/jsimd_arm_neon.S
tjbench.c
tjunittest.c

index 3a12fde..c52a89b 100644 (file)
@@ -38,7 +38,7 @@ endif
 
 
 SUBDIRS = java
-
+SUBDIRS += pkgconfig
 
 if WITH_TURBOJPEG
 
diff --git a/bmp.c b/bmp.c
index 9950a7a..8594a39 100644 (file)
--- a/bmp.c
+++ b/bmp.c
@@ -68,8 +68,16 @@ static void my_output_message(j_common_ptr cinfo)
 
 #define _throw(m) {snprintf(errStr, JMSG_LENGTH_MAX, "%s", m);  \
        retval=-1;  goto bailout;}
+#if _USE_PRODUCT_TV
+#define _throwunix(m) { \
+       char err_str[256]; \
+       strerror_r(errno, err_str, 256); \
+       snprintf(errStr, JMSG_LENGTH_MAX, "%s\n%s", m,  \
+       err_str);  retval=-1;  goto bailout;}
+#else
 #define _throwunix(m) {snprintf(errStr, JMSG_LENGTH_MAX, "%s\n%s", m,  \
        strerror(errno));  retval=-1;  goto bailout;}
+#endif
 
 
 static void pixelconvert(unsigned char *srcbuf, int srcpf, int srcbottomup,
index 6a55474..619affc 100644 (file)
@@ -99,8 +99,13 @@ if test "x${SUNCC}" = "xyes"; then
   fi
 fi
 
+AC_CHECK_DECL([_TIZEN_PRODUCT_TV], [with_pkg_config="yes"], [with_pkg_config="no"])
+if test "x${with_pkg_config}" = "xyes"; then
+  AC_DEFINE_UNQUOTED(COLOR_PICKER_ENABLE, [1], [tizen coloer picker enable])
+else
+  AC_DEFINE_UNQUOTED(COLOR_PICKER_ENABLE, [0], [tizen coloer picker disable])
+fi
 # Checks for libraries.
-
 # Checks for header files.
 AC_HEADER_STDC
 AC_CHECK_HEADERS([stddef.h stdlib.h locale.h string.h])
@@ -582,4 +587,5 @@ AC_CONFIG_FILES([libjpeg.map])
 AC_CONFIG_FILES([Makefile simd/Makefile])
 AC_CONFIG_FILES([java/Makefile])
 AC_CONFIG_FILES([md5/Makefile])
+AC_CONFIG_FILES([pkgconfig/Makefile pkgconfig/turbojpeg.pc])
 AC_OUTPUT
index b99a87e..2225577 100644 (file)
@@ -71,3 +71,5 @@
 
 /* The size of `size_t', as computed by sizeof. */
 #undef SIZEOF_SIZE_T
+
+#define COLOR_PICKER_ENABLE 0
index 199a628..d304b85 100644 (file)
@@ -158,21 +158,73 @@ decompress_onepass (j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
   JDIMENSION start_col, output_col;
   jpeg_component_info *compptr;
   inverse_DCT_method_ptr inverse_DCT;
+#if _USE_PRODUCT_TV
+  /* region decoding. this limits decode to the set of blocks +- 1 outside
+   * bounding blocks around the desired region to decode */
+  int blk1 = 0, blk2 = 0, skip = 0;
+
+  if ((cinfo->region_w > 0) && (cinfo->region_h > 0)) {
+    int bsz_w = 0, bsz_h = 0;
+
+    for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
+      compptr = cinfo->cur_comp_info[ci];
+      if (compptr->MCU_sample_width > bsz_w)
+        bsz_w = compptr->MCU_sample_width;
+      if ((compptr->MCU_height * 8) > bsz_h)
+        bsz_h = compptr->MCU_height * 8;
+    }
+    int _region_y = (int)cinfo->region_y;
+    _region_y = (_region_y>>1)<<1;
+    if (((int)cinfo->output_scanline < (_region_y - bsz_h - 1)) ||
+        ((int)cinfo->output_scanline > (_region_y + cinfo->region_h + bsz_h)))
+      skip = 1;
+    if (bsz_w != 0)
+      blk1 = (cinfo->region_x / bsz_w) - 1;
+    if (blk1 < 0)
+      blk1 = 0;
+    if (bsz_w != 0)
+      blk2 = ((cinfo->region_x + cinfo->region_w + bsz_w - 1) / bsz_w) + 1;
+    if (blk2 < 0)
+      blk2 = 0;
+  }
+#endif
 
   /* Loop to process as much as one whole iMCU row */
   for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row;
        yoffset++) {
     for (MCU_col_num = coef->MCU_ctr; MCU_col_num <= last_MCU_col;
          MCU_col_num++) {
+#if _USE_PRODUCT_TV
+      /* see if we need to skip this MCU or not */
+      if ((cinfo->region_w > 0) && (cinfo->region_h > 0)) {
+        if (!((MCU_col_num < blk1) || (MCU_col_num > blk2) || skip))
+          skip = 0;
+      }
+      /* if we are not skipping this MCU, zero it ready for huffman decode */
+      if (!skip)
+        jzero_far((void FAR *) coef->MCU_buffer[0],
+                  (size_t) (cinfo->blocks_in_MCU * sizeof(JBLOCK)));
+#endif
       /* Try to fetch an MCU.  Entropy decoder expects buffer to be zeroed. */
+#if _USE_PRODUCT_TV
+      jzero_far((void FAR *) coef->MCU_buffer[0],
+                (size_t) (cinfo->blocks_in_MCU * sizeof(JBLOCK)));
+#else
       jzero_far((void *) coef->MCU_buffer[0],
                 (size_t) (cinfo->blocks_in_MCU * sizeof(JBLOCK)));
+#endif
       if (! (*cinfo->entropy->decode_mcu) (cinfo, coef->MCU_buffer)) {
         /* Suspension forced; update state counters and exit */
         coef->MCU_vert_offset = yoffset;
         coef->MCU_ctr = MCU_col_num;
         return JPEG_SUSPENDED;
       }
+#if _USE_PRODUCT_TV
+      /* region decoding. this limits decode to the set of blocks +- 1 outside
+       * bounding blocks around the desired region to decode */
+      if (skip)
+        continue;
+#endif
       /* Determine where data should go in output_buf and do the IDCT thing.
        * We skip dummy blocks at the right and bottom edges (but blkn gets
        * incremented past them!).  Note the inner loop relies on having
index d1357af..2d99945 100644 (file)
@@ -466,7 +466,7 @@ get_dht (j_decompress_ptr cinfo)
     /* Here we just do minimal validation of the counts to avoid walking
      * off the end of our table space.  jdhuff.c will check more carefully.
      */
-    if (count > 256 || ((INT32) count) > length)
+    if (count < 0 || count > 256 || ((INT32) count) > length)
       ERREXIT(cinfo, JERR_BAD_HUFF_TABLE);
 
     for (i = 0; i < count; i++)
index e13adb9..a630a36 100644 (file)
--- a/jdmerge.c
+++ b/jdmerge.c
@@ -257,17 +257,34 @@ merged_2v_upsample (j_decompress_ptr cinfo,
   my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
   JSAMPROW work_ptrs[2];
   JDIMENSION num_rows;          /* number of rows returned to caller */
+#if _USE_PRODUCT_TV
+  int skip = 0;
+#endif
 
   if (upsample->spare_full) {
     /* If we have a spare row saved from a previous cycle, just return it. */
     JDIMENSION size = upsample->out_row_width;
     if (cinfo->out_color_space == JCS_RGB565)
       size = cinfo->output_width * 2;
+#if _USE_PRODUCT_TV
+    jcopy_sample_rows(& upsample->spare_row, 0, output_buf + *out_row_ctr, 0,
+                      1, upsample->out_row_width);
+#else
     jcopy_sample_rows(& upsample->spare_row, 0, output_buf + *out_row_ctr, 0,
                       1, size);
+#endif
     num_rows = 1;
     upsample->spare_full = FALSE;
   } else {
+#if _USE_PRODUCT_TV
+    int _region_y = (int)cinfo->region_y;
+    _region_y = (_region_y>>1)<<1;
+    if ((cinfo->region_w > 0) && (cinfo->region_h > 0)) {
+       if (((int)cinfo->output_scanline < _region_y) ||
+           ((int)cinfo->output_scanline >= (_region_y + (int)cinfo->region_h)))
+         skip = 1;
+    }
+#endif
     /* Figure number of rows to return to caller. */
     num_rows = 2;
     /* Not more than the distance to the end of the image. */
@@ -286,7 +303,12 @@ merged_2v_upsample (j_decompress_ptr cinfo,
       upsample->spare_full = TRUE;
     }
     /* Now do the upsampling. */
+#if _USE_PRODUCT_TV
+    if (!skip)
+      (*upsample->upmethod) (cinfo, input_buf, *in_row_group_ctr, work_ptrs);
+#else
     (*upsample->upmethod) (cinfo, input_buf, *in_row_group_ctr, work_ptrs);
+#endif
   }
 
   /* Adjust counts */
index 9615c5d..24509ef 100644 (file)
--- a/jpeglib.h
+++ b/jpeglib.h
@@ -35,7 +35,6 @@ extern "C" {
 #endif
 #endif
 
-
 /* Various constants determining the sizes of things.
  * All of these are specified by the JPEG standard, so don't change them
  * if you want to be compatible.
@@ -289,6 +288,18 @@ typedef struct jpeg_common_struct * j_common_ptr;
 typedef struct jpeg_compress_struct * j_compress_ptr;
 typedef struct jpeg_decompress_struct * j_decompress_ptr;
 
+typedef struct _Pick_Color_
+{
+    unsigned int sumR;
+    unsigned int sumG;
+    unsigned int sumB;
+    int enablePickColor;
+    int perc;
+    int x1;
+    int y1;
+    int x2;
+    int y2;
+}PickColor;
 
 /* Master record for a compression instance */
 
@@ -490,6 +501,10 @@ struct jpeg_decompress_struct {
 
   unsigned int scale_num, scale_denom; /* fraction by which to scale image */
 
+#if COLOR_PICKER_ENABLE == 1
+  unsigned int region_x, region_y, region_w, region_h; /* if region_w && region_h > 0, then use this region to decode. scale above is done prior to region select */
+#endif
+
   double output_gamma;          /* image gamma wanted in output */
 
   boolean buffered_image;       /* TRUE=multiple output passes */
@@ -702,6 +717,10 @@ struct jpeg_decompress_struct {
   struct jpeg_upsampler * upsample;
   struct jpeg_color_deconverter * cconvert;
   struct jpeg_color_quantizer * cquantize;
+
+#if COLOR_PICKER_ENABLE == 1
+  struct _Pick_Color_ *pick_color_data;
+#endif
 };
 
 
index 291b4f1..5114368 100644 (file)
--- a/jquant2.c
+++ b/jquant2.c
@@ -508,9 +508,17 @@ compute_color (j_decompress_ptr cinfo, boxptr boxp, int icolor)
       }
     }
 
+#if _USE_PRODUCT_TV
+        if(total != 0) {
+                cinfo->colormap[0][icolor] = (JSAMPLE) ((c0total + (total>>1)) / total);
+                cinfo->colormap[1][icolor] = (JSAMPLE) ((c1total + (total>>1)) / total);
+                cinfo->colormap[2][icolor] = (JSAMPLE) ((c2total + (total>>1)) / total);
+        }
+#else
   cinfo->colormap[0][icolor] = (JSAMPLE) ((c0total + (total>>1)) / total);
   cinfo->colormap[1][icolor] = (JSAMPLE) ((c1total + (total>>1)) / total);
   cinfo->colormap[2][icolor] = (JSAMPLE) ((c2total + (total>>1)) / total);
+#endif
 }
 
 
index eaa41e2..9d89e3e 100644 (file)
@@ -58,14 +58,18 @@ MD5FileChunk(const char *filename, char *buf, off_t ofs, off_t len)
        f = open(filename, O_RDONLY);
        if (f < 0)
                return 0;
-       if (fstat(f, &stbuf) < 0)
-               return 0;
+       if (fstat(f, &stbuf) < 0){
+        close(f);
+        return 0;
+    }
        if (ofs > stbuf.st_size)
                ofs = stbuf.st_size;
        if ((len == 0) || (len > stbuf.st_size - ofs))
                len = stbuf.st_size - ofs;
-       if (lseek(f, ofs, SEEK_SET) < 0)
-               return 0;
+       if (lseek(f, ofs, SEEK_SET) < 0){
+        close(f);
+        return 0;
+    }
        n = len;
        i = 0;
        while (n > 0) {
index c9a5d75..8ac24fd 100755 (executable)
@@ -64,6 +64,10 @@ files using the libjpeg library.
 cp %{SOURCE1001} .
 
 %build
+%if "%{?TIZEN_PRODUCT_TV}" == "1"
+echo "tizen_product_tv"
+export CFLAGS="$CFLAGS -D_TIZEN_PRODUCT_TV -D_USE_PRODUCT_TV"
+%endif
 autoreconf -fiv
 %configure --enable-shared --disable-static --with-jpeg8
 make %{?_smp_mflags}
@@ -111,6 +115,7 @@ rm -rf $RPM_BUILD_ROOT
 %files -n libjpeg-devel
 %defattr(-,root,root)
 %{_includedir}/*.h
+%{_libdir}/pkgconfig/turbojpeg.pc
 %{_libdir}/libturbojpeg.so
 %{_libdir}/libjpeg.so
 %doc coderules.txt jconfig.txt libjpeg.txt structure.txt example.c
diff --git a/pkgconfig/Makefile.am b/pkgconfig/Makefile.am
new file mode 100755 (executable)
index 0000000..fdf5f17
--- /dev/null
@@ -0,0 +1,16 @@
+pcfiles = turbojpeg.pc
+
+all-local: $(pcfiles)
+
+%.pc: %.pc
+       cp $< $@
+
+pkgconfigdir= $(libdir)/pkgconfig
+pkgconfig_DATA= $(pcfiles)
+
+CLEANFILES= $(pcfiles)
+
+pcinfiles= turbojpeg.pc.in
+
+EXTRA_DIST= $(pcinfiles)
+
diff --git a/pkgconfig/turbojpeg.pc.in b/pkgconfig/turbojpeg.pc.in
new file mode 100755 (executable)
index 0000000..df77158
--- /dev/null
@@ -0,0 +1,11 @@
+prefix=/usr
+exec_prefix=${prefix}
+libdir=${exec_prefix}/lib
+includedir=${prefix}/include
+
+Name: libturbojpeg
+Description: Loads and saves jpeg
+Version: @VERSION@
+Libs: -L${libdir} -lturbojpeg
+Libs.private: -lz -lm 
+Cflags: -I${includedir} 
diff --git a/rdppm.c b/rdppm.c
index 2e9b54d..e3aa1fd 100644 (file)
--- a/rdppm.c
+++ b/rdppm.c
@@ -416,10 +416,19 @@ start_input_ppm (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
       (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
                                   (size_t) (((long) maxval + 1L) * sizeof(JSAMPLE)));
     half_maxval = maxval / 2;
+#if _USE_PRODUCT_TV
+    if(maxval > 0) {
+      for (val = 0; val <= (INT32) maxval; val++) {
+        /* The multiplication here must be done in 32 bits to avoid overflow */
+        source->rescale[val] = (JSAMPLE) ((val*MAXJSAMPLE + half_maxval)/maxval);
+      }
+    }
+#else
     for (val = 0; val <= (INT32) maxval; val++) {
       /* The multiplication here must be done in 32 bits to avoid overflow */
       source->rescale[val] = (JSAMPLE) ((val*MAXJSAMPLE + half_maxval)/maxval);
     }
+#endif
   }
 }
 
index c5abd45..3905c97 100644 (file)
@@ -676,3 +676,13 @@ extern const int jconst_idct_float_sse2[];
 EXTERN(void) jsimd_idct_float_sse2
         (void * dct_table, JCOEFPTR coef_block, JSAMPARRAY output_buf,
          JDIMENSION output_col);
+
+/* TIZEN_PRODUCT_TV */
+EXTERN(void) jsimd_pick_color
+        JPP((JSAMPARRAY output_buf,
+                        void *pickColor,
+                        JDIMENSION out_width));
+
+EXTERN(void) jsimd_h2v1_fancy_upsample_neon
+        JPP((int max_v_samp_factor, JDIMENSION downsampled_width,
+             JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr));
index 4cbcf2d..d7460a0 100644 (file)
 #include <string.h>
 #include <ctype.h>
 
+#if _USE_PRODUCT_TV
+//Changes for JPEG GAMMA enhancement in thumbnail
+#include <unistd.h>
+#endif
+
 static unsigned int simd_support = ~0;
 
 #if defined(__linux__) || defined(ANDROID) || defined(__ANDROID__)
@@ -273,8 +278,24 @@ jsimd_ycc_rgb_convert (j_decompress_ptr cinfo,
       break;
   }
 
+#if _USE_PRODUCT_TV
+  if (simd_support & JSIMD_ARM_NEON) {
+    neonfct(cinfo->output_width, input_buf, input_row, output_buf, num_rows);
+    PickColor* pickColor = cinfo->pick_color_data;
+    if(pickColor && pickColor->enablePickColor && output_buf) {
+      int w = cinfo->output_width;
+      unsigned char *ptr = *output_buf;
+      if(pickColor->perc <= 0) {
+        w = pickColor->x2 - pickColor->x1 + 1;
+        ptr = (*output_buf) + (pickColor->x1 * 3);
+      }
+      jsimd_pick_color(ptr, pickColor, w);
+    }
+  }
+#else
   if (simd_support & JSIMD_ARM_NEON)
     neonfct(cinfo->output_width, input_buf, input_row, output_buf, num_rows);
+#endif
 }
 
 GLOBAL(void)
index 4d9685b..cf51541 100644 (file)
@@ -2437,3 +2437,161 @@ asm_function jsimd_h2v1_fancy_upsample_neon
 .purgem upsample16
 .purgem upsample32
 .purgem upsample_row
+
+#if _USE_PRODUCT_TV
+asm_function jsimd_pick_color
+
+@                RGB_BUFFER    .req r0
+@                RGB_RET       .req r1
+@                OUTPUT_WIDTH   .req r2
+
+               push            {r3, r4, r5, lr}
+               vpush           {d8-d15}
+               MOV r5, #0
+               VDUP.32 d0, r5  
+               VDUP.32 d1, r5  
+               VDUP.32 d2, r5  
+               VDUP.32 d3, r5  
+               VDUP.32 d4, r5  
+               VDUP.32 d5, r5  
+               VDUP.32 d6, r5  
+               VDUP.32 d7, r5  
+               VDUP.32 d8, r5  
+       
+               CMP   r2,#0x8
+               BCC   UNDER_8   
+          
+               CMP   r2,#0x10
+               BCC   UNDER_16   
+          
+               VLD3.8 {d0, d2, d4}, [r0]!
+               VLD3.8 {d1, d3, d5}, [r0]!
+
+               SUB r2, r2, #16
+               VPADDL.U8  q0,q0        
+               VPADDL.U8  q1,q1        
+               VPADDL.U8  q2,q2 
+               
+                     
+       PROCESS_LOOP:
+       
+               CMP r2, #0x10
+               BCC LOOP_BREAK                  
+       
+               SUB r2, r2, #16
+               CMP r2, #0
+               BLT LOOP_BREAK
+               
+               VLD3.8 {d6, d8, d10}, [r0]!
+               VLD3.8 {d7, d9, d11}, [r0]!
+
+               VPADAL.U8  q0,q3        
+               VPADAL.U8  q1,q4        
+               VPADAL.U8  q2,q5 
+
+               B PROCESS_LOOP
+
+       LOOP_BREAK:     
+               
+               VPADDL.U16 q0, q0
+               VPADDL.U16 q1, q1
+               VPADDL.U16 q2, q2
+               
+               VPADDL.U32 q0, q0
+               VPADDL.U32 q1, q1
+               VPADDL.U32 q2, q2
+
+               VADD.I64 d0, d0, d1
+               VADD.I64 d2, d2, d3
+               VADD.I64 d4, d4, d5
+               
+       PROCESS_REST:
+               CMP r2, #8
+               BLT PROCESS_U_8 @ignore less than 8 pixels as of now
+
+                VLD3.8 {d6, d7, d8}, [r0]!
+                VPADDL.U8  d6, d6
+                VPADDL.U8  d7, d7
+                VPADDL.U8  d8, d8
+
+                VPADDL.U16 d6, d6
+                VPADDL.U16 d7, d7
+                VPADDL.U16 d8, d8
+               
+                VPADDL.U32 d6, d6
+                VPADDL.U32 d7, d7
+                VPADDL.U32 d8, d8
+
+               VADD.I64 d0, d0, d6             
+               VADD.I64 d2, d2, d7             
+               VADD.I64 d4, d4, d8             
+               
+               SUB r2, r2, #8
+       
+       PROCESS_U_8:
+               CMP r2, #4
+               BLT PROCESS_U_4
+       
+               VLD3.8 {d6[0], d7[0], d8[0]}, [r0]!
+               VLD3.8 {d6[1], d7[1], d8[1]}, [r0]!
+               VLD3.8 {d6[2], d7[2], d8[2]}, [r0]!
+               VLD3.8 {d6[3], d7[3], d8[3]}, [r0]!
+
+               VPADDL.U8  d6, d6
+               VPADDL.U8  d7, d7
+               VPADDL.U8  d8, d8
+               
+               VPADDL.U16  d6, d6
+               VPADDL.U16  d7, d7
+               VPADDL.U16  d8, d8
+               
+               VADD.I64 d0, d0, d6             
+               VADD.I64 d2, d2, d7             
+               VADD.I64 d4, d4, d8             
+               
+               SUB r2, r2, #4
+
+        PROCESS_U_4:
+@                CMP r2, #2
+@                BLT PROCESS_U_2
+
+               B STORE
+
+
+       UNDER_16: 
+                               
+               VLD3.8 {d0, d2, d4}, [r0]!
+               VPADDL.U8  d0, d0
+               VPADDL.U8  d2, d2
+               VPADDL.U8  d4, d4
+       
+               VPADDL.U16 d0, d0
+               VPADDL.U16 d2, d2
+               VPADDL.U16 d4, d4
+
+               VPADDL.U32 d0, d0
+               VPADDL.U32 d2, d2
+               VPADDL.U32 d4, d4
+               
+               B STORE
+
+       STORE:
+               VMOV.U32  r3, d0[0]     
+               LDR r4, [r1]
+               ADD r4, r4, r3
+               STR r4, [r1]
+       
+               VMOV.U32 r3, d2[0]
+               LDR r4, [r1, #4]
+               ADD r4, r4, r3
+               STR r4, [r1, #4]
+               
+               VMOV.U32 r3, d4[0]
+               LDR r4, [r1, #8]
+               ADD r4, r4, r3
+               STR r4, [r1, #8]
+       
+       UNDER_8:
+               vpop            {d8-d15} 
+               pop             {r3, r4, r5, pc}
+#endif
\ No newline at end of file
index 29ed3d0..74cea6e 100644 (file)
--- a/tjbench.c
+++ b/tjbench.c
 #define _throw(op, err) {  \
        printf("ERROR in line %d while %s:\n%s\n", __LINE__, op, err);  \
   retval=-1;  goto bailout;}
+#if _USE_PRODUCT_TV
+#define _throwunix(m) { \
+       char err_str[256]; \
+       strerror_r(errno, err_str, 256); \
+       _throw(m, err_str) \
+}
+#else
 #define _throwunix(m) _throw(m, strerror(errno))
+#endif
 #define _throwtj(m) _throw(m, tjGetErrorStr())
 #define _throwbmp(m) _throw(m, bmpgeterr())
 
index 0c81cbe..b89d8a9 100644 (file)
@@ -383,7 +383,13 @@ void writeJPEG(unsigned char *jpegBuf, unsigned long jpegSize, char *filename)
        FILE *file=fopen(filename, "wb");
        if(!file || fwrite(jpegBuf, jpegSize, 1, file)!=1)
        {
+#if _USE_PRODUCT_TV
+               char err_str[256];
+               strerror_r(errno, err_str, 256);
+               printf("ERROR: Could not write to %s.\n%s\n", filename, err_str);
+#else
                printf("ERROR: Could not write to %s.\n%s\n", filename, strerror(errno));
+#endif
                bailout();
        }