]> granicus.if.org Git - openjpeg/commitdiff
[trunk] The two files in Issue145 have a precision < 8-bit:
authorMathieu Malaterre <mathieu.malaterre@gmail.com>
Tue, 29 May 2012 13:55:49 +0000 (13:55 +0000)
committerMathieu Malaterre <mathieu.malaterre@gmail.com>
Tue, 29 May 2012 13:55:49 +0000 (13:55 +0000)
therefore 'jp2_read_pclr' must be changed.

j2k_to_image fails to create RGB/RGBA images with a
precision < 8-bit: therefore 'imagetopng' must be
changed.
Fixes issue 145

applications/codec/convert.c
libopenjpeg/jp2.c

index dee780d4a70b0827e0ee827a27a22840fab0601f..59af469b471798f6132129a79b76c0c617273a85 100644 (file)
@@ -3277,18 +3277,27 @@ int imagetopng(opj_image_t * image, const char *write_idf)
        int *red, *green, *blue, *alpha;
        unsigned char *row_buf, *d;
        int has_alpha, width, height, nr_comp, color_type;
-       int adjustR, adjustG, adjustB, x, y, fails, is16, force16;
-  int opj_prec, prec, ushift, dshift;
+       int adjustR, adjustG, adjustB, adjustA, x, y, fails;
+       int prec, ushift, dshift, is16, force16, force8;
        unsigned short mask = 0xffff;
        png_color_8 sig_bit;
 
-       is16 = force16 = ushift = dshift = 0; fails = 1;
-       prec = opj_prec = image->comps[0].prec;
+       is16 = force16 = force8 = ushift = dshift = 0; fails = 1;
+       prec = image->comps[0].prec;
+       nr_comp = image->numcomps;
 
        if(prec > 8 && prec < 16)
    {
-        prec = 16; force16 = 1;
+       ushift = 16 - prec; dshift = prec - ushift;
+       prec = 16; force16 = 1;
    }
+       else
+       if(prec < 8 && nr_comp > 1)/* GRAY_ALPHA, RGB, RGB_ALPHA */
+   {
+       ushift = 8 - prec; dshift = 8 - ushift;
+       prec = 8; force8 = 1;
+   }
+
        if(prec != 1 && prec != 2 && prec != 4 && prec != 8 && prec != 16)
    {
        fprintf(stderr,"imagetopng: can not create %s"
@@ -3336,6 +3345,14 @@ int imagetopng(opj_image_t * image, const char *write_idf)
  * PNG_INTERLACE_ADAM7, and the compression_type and filter_type MUST
  * currently be PNG_COMPRESSION_TYPE_BASE and PNG_FILTER_TYPE_BASE. 
  * REQUIRED
+ *
+ * ERRORS:
+ *
+ * color_type == PNG_COLOR_TYPE_PALETTE && bit_depth > 8
+ * color_type == PNG_COLOR_TYPE_RGB && bit_depth < 8
+ * color_type == PNG_COLOR_TYPE_GRAY_ALPHA && bit_depth < 8
+ * color_type == PNG_COLOR_TYPE_RGB_ALPHA) && bit_depth < 8
+ * 
 */
        png_set_compression_level(png, Z_BEST_COMPRESSION);
 
@@ -3349,8 +3366,6 @@ int imagetopng(opj_image_t * image, const char *write_idf)
        else
        if(prec == 1) mask = 0x0001;
 
-       nr_comp = image->numcomps;
-
        if(nr_comp >= 3
     && image->comps[0].dx == image->comps[1].dx
     && image->comps[1].dx == image->comps[2].dx
@@ -3379,11 +3394,13 @@ int imagetopng(opj_image_t * image, const char *write_idf)
        sig_bit.alpha = prec;
        alpha = image->comps[3].data; 
        color_type = PNG_COLOR_TYPE_RGB_ALPHA;
+       adjustA = (image->comps[3].sgnd ? 1 << (image->comps[3].prec - 1) : 0);
   }
        else 
   {
        sig_bit.alpha = 0; alpha = NULL;
        color_type = PNG_COLOR_TYPE_RGB;
+       adjustA = 0;
   }
        png_set_sBIT(png, info, &sig_bit);
 
@@ -3391,17 +3408,12 @@ int imagetopng(opj_image_t * image, const char *write_idf)
         color_type,
         PNG_INTERLACE_NONE,
         PNG_COMPRESSION_TYPE_BASE,  PNG_FILTER_TYPE_BASE);
-
 /*=============================*/
        png_write_info(png, info);
 /*=============================*/
-       if(opj_prec < 8)
+       if(prec < 8)
   {
        png_set_packing(png);
-  }
-       if(force16)
-  {
-       ushift = 16 - opj_prec; dshift = opj_prec - ushift;     
   }
     adjustR = (image->comps[0].sgnd ? 1 << (image->comps[0].prec - 1) : 0);
     adjustG = (image->comps[1].sgnd ? 1 << (image->comps[1].prec - 1) : 0);
@@ -3437,21 +3449,40 @@ int imagetopng(opj_image_t * image, const char *write_idf)
 
                if(has_alpha)
          {
-               v = *alpha++;
+               v = *alpha + adjustA; ++alpha;
                
                if(force16) { v = (v<<ushift) + (v>>dshift); }
 
                *d++ = (unsigned char)(v>>8); *d++ = (unsigned char)v;
          }
                continue;
-          }
-               *d++ = (unsigned char)((*red + adjustR) & mask); ++red;
-               *d++ = (unsigned char)((*green + adjustG) & mask); ++green;
-               *d++ = (unsigned char)((*blue + adjustB) & mask); ++blue;
+          }/* if(is16) */
+
+               v = *red + adjustR; ++red;
+
+               if(force8) { v = (v<<ushift) + (v>>dshift); }
+
+               *d++ = (unsigned char)(v & mask);
+
+               v = *green + adjustG; ++green;
+
+               if(force8) { v = (v<<ushift) + (v>>dshift); }
+
+               *d++ = (unsigned char)(v & mask);
+
+               v = *blue + adjustB; ++blue;
+
+               if(force8) { v = (v<<ushift) + (v>>dshift); }
+
+               *d++ = (unsigned char)(v & mask);
 
                if(has_alpha)
           {
-               *d++ = (unsigned char)(*alpha & mask); ++alpha;
+               v = *alpha + adjustA; ++alpha;
+
+               if(force8) { v = (v<<ushift) + (v>>dshift); }
+
+               *d++ = (unsigned char)(v & mask);
           }
  }     /* for(x) */
 
@@ -3472,13 +3503,9 @@ int imagetopng(opj_image_t * image, const char *write_idf)
 
        red = image->comps[0].data;
 
-    if(force16)
-  {
-    ushift = 16 - opj_prec; dshift = opj_prec - ushift;
-  }
     sig_bit.gray = prec;
     sig_bit.red = sig_bit.green = sig_bit.blue = sig_bit.alpha = 0;
-       alpha = NULL;
+       alpha = NULL; adjustA = 0;
        color_type = PNG_COLOR_TYPE_GRAY;
 
     if(nr_comp == 2) 
@@ -3486,6 +3513,7 @@ int imagetopng(opj_image_t * image, const char *write_idf)
        has_alpha = 1; sig_bit.alpha = prec;
        alpha = image->comps[1].data;
        color_type = PNG_COLOR_TYPE_GRAY_ALPHA;
+       adjustA = (image->comps[1].sgnd ? 1 << (image->comps[1].prec - 1) : 0);
   }
     width = image->comps[0].w;
     height = image->comps[0].h;
@@ -3501,7 +3529,7 @@ int imagetopng(opj_image_t * image, const char *write_idf)
 /*=============================*/
        adjustR = (image->comps[0].sgnd ? 1 << (image->comps[0].prec - 1) : 0);
 
-       if(opj_prec < 8)
+       if(prec < 8)
   {
        png_set_packing(png);
   }
@@ -3547,11 +3575,19 @@ int imagetopng(opj_image_t * image, const char *write_idf)
 
                for(x = 0; x < width; ++x)
           {
-               *d++ = (unsigned char)((*red + adjustR) & mask); ++red;
+               v = *red + adjustR; ++red;
+
+               if(force8) { v = (v<<ushift) + (v>>dshift); }
+
+               *d++ = (unsigned char)(v & mask);
 
                if(has_alpha)
          {
-               *d++ = (unsigned char)(*alpha & mask); ++alpha;
+               v = *alpha + adjustA; ++alpha;
+
+               if(force8) { v = (v<<ushift) + (v>>dshift); }
+
+               *d++ = (unsigned char)(v & mask);
          }
           }/* for(x) */
 
index c4cc9fe95c9804a053d8ffa7aa04a52ff55b24bf..73744f7e0bb6ae027a4777003be86d505b07b852 100644 (file)
@@ -1160,7 +1160,7 @@ static opj_bool jp2_read_pclr(opj_jp2_t *jp2, opj_cio_t *cio,
        for(i = 0; i < nr_channels; ++i)
   {
 /* Cji */
-       *entries++ = cio_read(cio, channel_size[i]>>3);
+       *entries++ = cio_read(cio, (channel_size[i]+7)>>3);
   }
    }
 
@@ -1230,9 +1230,10 @@ opj_bool jp2_read_pclr_v2(       opj_jp2_v2_t *jp2,
 
        for(j = 0; j < nr_entries; ++j) {
                for(i = 0; i < nr_channels; ++i) {
-                       /**entries++ = cio_read(cio, channel_size[i]>>3); */
-                       opj_read_bytes(p_pclr_header_data, &l_value , channel_size[i]>>3);      /* Cji */
-                       p_pclr_header_data += channel_size[i]>>3;
+                       int bytes_to_read = (channel_size[i]+7)>>3;
+
+                       opj_read_bytes(p_pclr_header_data, &l_value , bytes_to_read);   /* Cji */
+                       p_pclr_header_data += bytes_to_read;
                        *entries = (OPJ_UINT32) l_value;
                        entries++;
                }