Update tiftoimage to support more input TIF formats
authormayeut <mayeut@users.noreply.github.com>
Tue, 14 Jul 2015 21:51:02 +0000 (23:51 +0200)
committermayeut <mayeut@users.noreply.github.com>
Tue, 14 Jul 2015 21:51:02 +0000 (23:51 +0200)
Update uclouvain/openjpeg#322
Update uclouvain/openjpeg#264

src/bin/jp2/CMakeLists.txt
src/bin/jp2/convert.c
src/bin/jp2/converttif.c [new file with mode: 0644]
tests/CMakeLists.txt

index 4cf4aecf917e70473b4338ac618ef0a461d8f92a..95d1430d7a9179833be801cc82f3327f4045c125 100644 (file)
@@ -8,6 +8,10 @@ set(common_SRCS
   ${OPENJPEG_SOURCE_DIR}/src/bin/common/color.c
   ${OPENJPEG_SOURCE_DIR}/src/bin/common/opj_getopt.c
   )
+  
+if(OPJ_HAVE_LIBTIFF)
+       list(APPEND common_SRCS converttif.c)
+endif()
 
 # Headers file are located here:
 include_directories(
index 5cde4fbd33a1001c31e173f8cde5e70041adcc6b..bb8cfdac88d0280892d7cbbb5013c09cf5b84de7 100644 (file)
@@ -149,6 +149,7 @@ void scale_component(opj_image_comp_t* component, OPJ_UINT32 precision)
                        l_data[i] >>= shift;
                }
        }
+       component->bpp = precision;
        component->prec = precision;
 }
 
@@ -1582,769 +1583,6 @@ if(v > 65535) v = 65535; else if(v < 0) v = 0;
     return 0;
 }/* imagetopnm() */
 
-#ifdef OPJ_HAVE_LIBTIFF
-/* -->> -->> -->> -->>
-
-    TIFF IMAGE FORMAT
-
- <<-- <<-- <<-- <<-- */
-
-int imagetotif(opj_image_t * image, const char *outfile) 
-{
-    int width, height, imgsize;
-    int bps,index,adjust, sgnd;
-    int ushift, dshift, has_alpha, force16;
-    TIFF *tif;
-    tdata_t buf;
-    tstrip_t strip;
-    tsize_t strip_size;
-
-    ushift = dshift = force16 = has_alpha = 0;
-    bps = (int)image->comps[0].prec;
-
-    if(bps > 8 && bps < 16)
-    {
-        ushift = 16 - bps; dshift = bps - ushift;
-        bps = 16; force16 = 1;
-    }
-
-    if(bps != 8 && bps != 16)
-    {
-        fprintf(stderr,"imagetotif: Bits=%d, Only 8 and 16 bits implemented\n",
-                bps);
-        fprintf(stderr,"\tAborting\n");
-        return 1;
-    }
-    tif = TIFFOpen(outfile, "wb");
-
-    if (!tif)
-    {
-        fprintf(stderr, "imagetotif:failed to open %s for writing\n", outfile);
-        return 1;
-    }
-    sgnd = (int)image->comps[0].sgnd;
-    adjust = sgnd ? 1 << (image->comps[0].prec - 1) : 0;
-
-    if(image->numcomps >= 3
-            && image->comps[0].dx == image->comps[1].dx
-            && image->comps[1].dx == image->comps[2].dx
-            && image->comps[0].dy == image->comps[1].dy
-            && image->comps[1].dy == image->comps[2].dy
-            && image->comps[0].prec == image->comps[1].prec
-            && image->comps[1].prec == image->comps[2].prec)
-    {
-        has_alpha = (image->numcomps == 4);
-
-        width   = (int)image->comps[0].w;
-        height  = (int)image->comps[0].h;
-        imgsize = width * height ;
-
-        TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, width);
-        TIFFSetField(tif, TIFFTAG_IMAGELENGTH, height);
-        TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 3 + has_alpha);
-        TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, bps);
-        TIFFSetField(tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
-        TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
-        TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
-        TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, 1);
-        strip_size = TIFFStripSize(tif);
-        buf = _TIFFmalloc(strip_size);
-        index=0;
-
-        for(strip = 0; strip < TIFFNumberOfStrips(tif); strip++)
-        {
-            unsigned char *dat8;
-            tsize_t i, ssize, last_i = 0;
-            int step, restx;
-            ssize = TIFFStripSize(tif);
-            dat8 = (unsigned char*)buf;
-
-            if(bps == 8)
-            {
-                step = 3 + has_alpha;
-                restx = step - 1;
-
-                for(i=0; i < ssize - restx; i += step)
-                {
-                    int r, g, b, a = 0;
-
-                    if(index < imgsize)
-                    {
-                        r = image->comps[0].data[index];
-                        g = image->comps[1].data[index];
-                        b = image->comps[2].data[index];
-                        if(has_alpha) a = image->comps[3].data[index];
-
-                        if(sgnd)
-                        {
-                            r += adjust;
-                            g += adjust;
-                            b += adjust;
-                            if(has_alpha) a += adjust;
-                        }
-               if(r > 255) r = 255; else if(r < 0) r = 0;
-                        dat8[i+0] = (unsigned char)r ;
-               if(g > 255) g = 255; else if(g < 0) g = 0;
-                        dat8[i+1] = (unsigned char)g ;
-               if(b > 255) b = 255; else if(b < 0) b = 0;
-                        dat8[i+2] = (unsigned char)b ;
-               if(has_alpha) 
-        {
-               if(a > 255) a = 255; else if(a < 0) a = 0;
-               dat8[i+3] = (unsigned char)a;
-        }
-
-                        index++;
-                        last_i = i + step;
-                    }
-                    else
-                        break;
-                }/*for(i = 0;)*/
-
-                if(last_i < ssize)
-                {
-                    for(i = last_i; i < ssize; i += step)
-                    {
-                        int r, g, b, a = 0;
-
-                        if(index < imgsize)
-                        {
-                            r = image->comps[0].data[index];
-                            g = image->comps[1].data[index];
-                            b = image->comps[2].data[index];
-                            if(has_alpha) a = image->comps[3].data[index];
-
-                            if(sgnd)
-                            {
-                                r += adjust;
-                                g += adjust;
-                                b += adjust;
-                                if(has_alpha) a += adjust;
-                            }
-               if(r > 255) r = 255; else if(r < 0) r = 0;
-               if(g > 255) g = 255; else if(g < 0) g = 0;
-               if(b > 255) b = 255; else if(b < 0) b = 0;
-
-                            dat8[i+0] = (unsigned char)r ;
-                            if(i+1 < ssize) dat8[i+1] = (unsigned char)g ;  else break;
-                            if(i+2 < ssize) dat8[i+2] = (unsigned char)b ;  else break;
-                            if(has_alpha)
-                            {
-               if(a > 255) a = 255; else if(a < 0) a = 0;
-
-                                if(i+3 < ssize) dat8[i+3] = (unsigned char)a ;  else break;
-                            }
-                            index++;
-                        }
-                        else
-                            break;
-                    }/*for(i)*/
-                }/*if(last_i < ssize)*/
-
-            }  /*if(bps == 8)*/
-            else
-                if(bps == 16)
-                {
-                    step = 6 + has_alpha + has_alpha;
-                    restx = step - 1;
-
-                    for(i = 0; i < ssize - restx ; i += step)
-                    {
-                        int r, g, b, a = 0;
-
-                        if(index < imgsize)
-                        {
-                            r = image->comps[0].data[index];
-                            g = image->comps[1].data[index];
-                            b = image->comps[2].data[index];
-                            if(has_alpha) a = image->comps[3].data[index];
-
-                            if(sgnd)
-                            {
-                                r += adjust;
-                                g += adjust;
-                                b += adjust;
-                                if(has_alpha) a += adjust;
-                            }
-                            if(force16)
-                            {
-                                r = (r<<ushift) + (r>>dshift);
-                                g = (g<<ushift) + (g>>dshift);
-                                b = (b<<ushift) + (b>>dshift);
-                                if(has_alpha) a = (a<<ushift) + (a>>dshift);
-                            }
-               if(r > 65535) r = 65535; else if(r < 0) r = 0;
-               if(g > 65535) g = 65535; else if(g < 0) g = 0;
-               if(b > 65535) b = 65535; else if(b < 0) b = 0;
-
-                            dat8[i+0] =  (unsigned char)r;/*LSB*/
-                            dat8[i+1] = (unsigned char)(r >> 8);/*MSB*/
-                            dat8[i+2] =  (unsigned char)g;
-                            dat8[i+3] = (unsigned char)(g >> 8);
-                            dat8[i+4] =  (unsigned char)b;
-                            dat8[i+5] = (unsigned char)(b >> 8);
-                            if(has_alpha)
-                            {
-               if(a > 65535) a = 65535; else if(a < 0) a = 0;
-                                dat8[i+6] =  (unsigned char)a;
-                                dat8[i+7] = (unsigned char)(a >> 8);
-                            }
-                            index++;
-                            last_i = i + step;
-                        }
-                        else
-                            break;
-                    }/*for(i = 0;)*/
-
-                    if(last_i < ssize)
-                    {
-                        for(i = last_i ; i < ssize ; i += step)
-                        {
-                            int r, g, b, a = 0;
-
-                            if(index < imgsize)
-                            {
-                                r = image->comps[0].data[index];
-                                g = image->comps[1].data[index];
-                                b = image->comps[2].data[index];
-                                if(has_alpha) a = image->comps[3].data[index];
-
-                                if(sgnd)
-                                {
-                                    r += adjust;
-                                    g += adjust;
-                                    b += adjust;
-                                    if(has_alpha) a += adjust;
-                                }
-                                if(force16)
-                                {
-                                    r = (r<<ushift) + (r>>dshift);
-                                    g = (g<<ushift) + (g>>dshift);
-                                    b = (b<<ushift) + (b>>dshift);
-                                    if(has_alpha) a = (a<<ushift) + (a>>dshift);
-                                }
-               if(r > 65535) r = 65535; else if(r < 0) r = 0;
-               if(g > 65535) g = 65535; else if(g < 0) g = 0;
-               if(b > 65535) b = 65535; else if(b < 0) b = 0;
-
-                                dat8[i+0] = (unsigned char) r;/*LSB*/
-                                if(i+1 < ssize) dat8[i+1] = (unsigned char)(r >> 8);else break;/*MSB*/
-                                if(i+2 < ssize) dat8[i+2] = (unsigned char) g;      else break;
-                                if(i+3 < ssize) dat8[i+3] = (unsigned char)(g >> 8);else break;
-                                if(i+4 < ssize) dat8[i+4] = (unsigned char) b;      else break;
-                                if(i+5 < ssize) dat8[i+5] = (unsigned char)(b >> 8);else break;
-
-                                if(has_alpha)
-                                {
-               if(a > 65535) a = 65535; else if(a < 0) a = 0;
-                                    if(i+6 < ssize) dat8[i+6] = (unsigned char)a; else break;
-                                    if(i+7 < ssize) dat8[i+7] = (unsigned char)(a >> 8); else break;
-                                }
-                                index++;
-                            }
-                            else
-                                break;
-                        }/*for(i)*/
-                    }/*if(last_i < ssize)*/
-
-                }/*if(bps == 16)*/
-            (void)TIFFWriteEncodedStrip(tif, strip, (void*)buf, strip_size);
-        }/*for(strip = 0; )*/
-
-        _TIFFfree((void*)buf);
-        TIFFClose(tif);
-
-        return 0;
-    }/*RGB(A)*/
-
-    if(image->numcomps == 1 /* GRAY */
-            || (   image->numcomps == 2 /* GRAY_ALPHA */
-                   && image->comps[0].dx == image->comps[1].dx
-                   && image->comps[0].dy == image->comps[1].dy
-                   && image->comps[0].prec == image->comps[1].prec))
-    {
-        int step;
-
-        has_alpha = (image->numcomps == 2);
-
-        width   = (int)image->comps[0].w;
-        height  = (int)image->comps[0].h;
-        imgsize = width * height;
-
-        /* Set tags */
-        TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, width);
-        TIFFSetField(tif, TIFFTAG_IMAGELENGTH, height);
-        TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 1 + has_alpha);
-        TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, bps);
-        TIFFSetField(tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
-        TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
-        TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK);
-        TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, 1);
-
-        /* Get a buffer for the data */
-        strip_size = TIFFStripSize(tif);
-        buf = _TIFFmalloc(strip_size);
-        index = 0;
-
-        for(strip = 0; strip < TIFFNumberOfStrips(tif); strip++)
-        {
-            unsigned char *dat8;
-            tsize_t i, ssize = TIFFStripSize(tif);
-            dat8 = (unsigned char*)buf;
-
-            if(bps == 8)
-            {
-                step = 1 + has_alpha;
-
-                for(i=0; i < ssize; i += step)
-                {
-                    if(index < imgsize)
-                    {
-                        int r, a = 0;
-
-                        r = image->comps[0].data[index];
-                        if(has_alpha) a = image->comps[1].data[index];
-
-                        if(sgnd)
-                        {
-                            r += adjust;
-                            if(has_alpha) a += adjust;
-                        }
-               if(r > 255) r = 255; else if(r < 0) r = 0;
-                        dat8[i+0] = (unsigned char)r;
-
-               if(has_alpha) 
-        {
-               if(a > 255) a = 255; else if(a < 0) a = 0;
-               dat8[i+1] = (unsigned char)a;
-                    }
-               index++;
-         }
-                    else
-                        break;
-          }/*for(i )*/
-            }/*if(bps == 8*/
-            else
-                if(bps == 16)
-                {
-                    step = 2 + has_alpha + has_alpha;
-
-                    for(i=0; i < ssize; i += step)
-                    {
-                        if(index < imgsize)
-                        {
-                            int r, a = 0;
-
-                            r = image->comps[0].data[index];
-                            if(has_alpha) a = image->comps[1].data[index];
-
-                            if(sgnd)
-                            {
-                                r += adjust;
-                                if(has_alpha) a += adjust;
-                            }
-                            if(force16)
-                            {
-                                r = (r<<ushift) + (r>>dshift);
-                                if(has_alpha) a = (a<<ushift) + (a>>dshift);
-                            }
-               if(r > 65535) r = 65535; else if(r < 0) r = 0;
-                            dat8[i+0] = (unsigned char)r;/*LSB*/
-                            dat8[i+1] = (unsigned char)(r >> 8);/*MSB*/
-                            if(has_alpha)
-                            {
-               if(a > 65535) a = 65535; else if(a < 0) a = 0;
-                                dat8[i+2] = (unsigned char)a;
-                                dat8[i+3] = (unsigned char)(a >> 8);
-                            }
-                            index++;
-                        }/*if(index < imgsize)*/
-                        else
-                            break;
-                    }/*for(i )*/
-                }
-            (void)TIFFWriteEncodedStrip(tif, strip, (void*)buf, strip_size);
-        }/*for(strip*/
-
-        _TIFFfree(buf);
-        TIFFClose(tif);
-
-        return 0;
-    }
-
-    TIFFClose(tif);
-
-    fprintf(stderr,"imagetotif: Bad color format.\n"
-            "\tOnly RGB(A) and GRAY(A) has been implemented\n");
-    fprintf(stderr,"\tFOUND: numcomps(%d)\n\tAborting\n",
-            image->numcomps);
-
-    return 1;
-}/* imagetotif() */
-
-/*
- * libtiff/tif_getimage.c : 1,2,4,8,16 bitspersample accepted
- * CINEMA                 : 12 bit precision
-*/
-opj_image_t* tiftoimage(const char *filename, opj_cparameters_t *parameters)
-{
-    int subsampling_dx = parameters->subsampling_dx;
-    int subsampling_dy = parameters->subsampling_dy;
-    TIFF *tif;
-    tdata_t buf;
-    tstrip_t strip;
-    tsize_t strip_size;
-    int j, numcomps, w, h,index;
-    OPJ_COLOR_SPACE color_space;
-    opj_image_cmptparm_t cmptparm[4]; /* RGBA */
-    opj_image_t *image = NULL;
-    int imgsize = 0;
-    int has_alpha = 0;
-    unsigned short tiBps, tiPhoto, tiSf, tiSpp, tiPC;
-    unsigned int tiWidth, tiHeight;
-    OPJ_BOOL is_cinema = OPJ_IS_CINEMA(parameters->rsiz);
-
-    tif = TIFFOpen(filename, "r");
-
-    if(!tif)
-    {
-        fprintf(stderr, "tiftoimage:Failed to open %s for reading\n", filename);
-        return 0;
-    }
-    tiBps = tiPhoto = tiSf = tiSpp = tiPC = 0;
-    tiWidth = tiHeight = 0;
-
-    TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &tiWidth);
-    TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &tiHeight);
-    TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &tiBps);
-    TIFFGetField(tif, TIFFTAG_SAMPLEFORMAT, &tiSf);
-    TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &tiSpp);
-    TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &tiPhoto);
-    TIFFGetField(tif, TIFFTAG_PLANARCONFIG, &tiPC);
-    w= (int)tiWidth;
-    h= (int)tiHeight;
-
-    if(tiBps != 8 && tiBps != 16 && tiBps != 12) tiBps = 0;
-    if(tiPhoto != 1 && tiPhoto != 2) tiPhoto = 0;
-
-    if( !tiBps || !tiPhoto)
-    {
-        if( !tiBps)
-     fprintf(stderr,"tiftoimage: Bits=%d, Only 8 and 16 bits"
-                    " implemented\n",tiBps);
-        else
-            if( !tiPhoto)
-                fprintf(stderr,"tiftoimage: Bad color format %d.\n\tOnly RGB(A)"
-                        " and GRAY(A) has been implemented\n",(int) tiPhoto);
-
-        fprintf(stderr,"\tAborting\n");
-        TIFFClose(tif);
-
-        return NULL;
-    }
-
-    {/* From: tiff-4.0.x/libtiff/tif_getimage.c : */
-        uint16* sampleinfo;
-        uint16 extrasamples;
-
-        TIFFGetFieldDefaulted(tif, TIFFTAG_EXTRASAMPLES,
-                              &extrasamples, &sampleinfo);
-
-        if(extrasamples >= 1)
-        {
-            switch(sampleinfo[0])
-            {
-            case EXTRASAMPLE_UNSPECIFIED:
-                /* Workaround for some images without correct info about alpha channel
-*/
-                if(tiSpp > 3)
-                    has_alpha = 1;
-                break;
-
-            case EXTRASAMPLE_ASSOCALPHA: /* data pre-multiplied */
-            case EXTRASAMPLE_UNASSALPHA: /* data not pre-multiplied */
-                has_alpha = 1;
-                break;
-            }
-        }
-        else /* extrasamples == 0 */
-            if(tiSpp == 4 || tiSpp == 2) has_alpha = 1;
-    }
-
-    /* initialize image components
-*/ 
-    memset(&cmptparm[0], 0, 4 * sizeof(opj_image_cmptparm_t));
-
-    if ((tiPhoto == PHOTOMETRIC_RGB) && (is_cinema)) {
-        fprintf(stdout,"WARNING:\n"
-                "Input image bitdepth is %d bits\n"
-                "TIF conversion has automatically rescaled to 12-bits\n"
-                "to comply with cinema profiles.\n",
-                tiBps);
-    }
-
-    if(tiPhoto == PHOTOMETRIC_RGB) /* RGB(A) */
-    {
-        numcomps = 3 + has_alpha;
-        color_space = OPJ_CLRSPC_SRGB;
-
-        /*#define USETILEMODE*/
-        for(j = 0; j < numcomps; j++)
-        {
-            if(is_cinema)
-            {
-                cmptparm[j].prec = 12;
-                cmptparm[j].bpp = 12;
-            }
-            else
-            {
-                cmptparm[j].prec = tiBps;
-                cmptparm[j].bpp = tiBps;
-            }
-            cmptparm[j].dx = (OPJ_UINT32)subsampling_dx;
-            cmptparm[j].dy = (OPJ_UINT32)subsampling_dy;
-            cmptparm[j].w = (OPJ_UINT32)w;
-            cmptparm[j].h = (OPJ_UINT32)h;
-#ifdef USETILEMODE
-            cmptparm[j].x0 = 0;
-            cmptparm[j].y0 = 0;
-#endif
-        }
-
-#ifdef USETILEMODE
-        image = opj_image_tile_create(numcomps,&cmptparm[0],color_space);
-#else
-        image = opj_image_create((OPJ_UINT32)numcomps, &cmptparm[0], color_space);
-#endif
-
-        if(!image)
-        {
-            TIFFClose(tif);
-            return NULL;
-        }
-        /* set image offset and reference grid
-*/
-        image->x0 = (OPJ_UINT32)parameters->image_offset_x0;
-        image->y0 = (OPJ_UINT32)parameters->image_offset_y0;
-        image->x1 =    !image->x0 ? (OPJ_UINT32)(w - 1) * (OPJ_UINT32)subsampling_dx + 1 :
-                                 image->x0 + (OPJ_UINT32)(w - 1) * (OPJ_UINT32)subsampling_dx + 1;
-        image->y1 =    !image->y0 ? (OPJ_UINT32)(h - 1) * (OPJ_UINT32)subsampling_dy + 1 :
-                                 image->y0 + (OPJ_UINT32)(h - 1) * (OPJ_UINT32)subsampling_dy + 1;
-
-        buf = _TIFFmalloc(TIFFStripSize(tif));
-
-        strip_size=TIFFStripSize(tif);
-        index = 0;
-        imgsize = (int)(image->comps[0].w * image->comps[0].h);
-        /* Read the Image components
-*/
-        for(strip = 0; strip < TIFFNumberOfStrips(tif); strip++)
-        {
-            unsigned char *dat8;
-            int step;
-            tsize_t i, ssize;
-            ssize = TIFFReadEncodedStrip(tif, strip, buf, strip_size);
-            dat8 = (unsigned char*)buf;
-
-            if(tiBps == 16)
-            {
-                step = 6 + has_alpha + has_alpha;
-
-                for(i = 0; i < ssize; i += step)
-                {
-                    if(index < imgsize)
-                    {
-                        image->comps[0].data[index] = ( dat8[i+1] << 8 ) | dat8[i+0]; /* R */
-                        image->comps[1].data[index] = ( dat8[i+3] << 8 ) | dat8[i+2]; /* G */
-                        image->comps[2].data[index] = ( dat8[i+5] << 8 ) | dat8[i+4]; /* B */
-                        if(has_alpha)
-                            image->comps[3].data[index] = ( dat8[i+7] << 8 ) | dat8[i+6];
-
-                        if(is_cinema)
-                        {
-                            /* Rounding 16 to 12 bits
-*/
-                            image->comps[0].data[index] =
-                                    (image->comps[0].data[index] + 0x08) >> 4 ;
-                            image->comps[1].data[index] =
-                                    (image->comps[1].data[index] + 0x08) >> 4 ;
-                            image->comps[2].data[index] =
-                                    (image->comps[2].data[index] + 0x08) >> 4 ;
-                            if(has_alpha)
-                                image->comps[3].data[index] =
-                                        (image->comps[3].data[index] + 0x08) >> 4 ;
-                        }
-                        index++;
-                    }
-                    else
-                        break;
-                }/*for(i = 0)*/
-            }/*if(tiBps == 16)*/
-            else
-                if(tiBps == 8)
-                {
-                    step = 3 + has_alpha;
-
-                    for(i = 0; i < ssize; i += step)
-                    {
-                        if(index < imgsize)
-                        {
-#ifndef USETILEMODE
-                            image->comps[0].data[index] = dat8[i+0];/* R */
-                            image->comps[1].data[index] = dat8[i+1];/* G */
-                            image->comps[2].data[index] = dat8[i+2];/* B */
-                            if(has_alpha)
-                                image->comps[3].data[index] = dat8[i+3];
-#endif
-
-                            if(is_cinema)
-                            {
-                                /* Rounding 8 to 12 bits
-*/
-#ifndef USETILEMODE
-                                image->comps[0].data[index] = image->comps[0].data[index] << 4 ;
-                                image->comps[1].data[index] = image->comps[1].data[index] << 4 ;
-                                image->comps[2].data[index] = image->comps[2].data[index] << 4 ;
-                                if(has_alpha)
-                                    image->comps[3].data[index] = image->comps[3].data[index] << 4 ;
-#endif
-                            }
-                            index++;
-                        }/*if(index*/
-                        else
-                            break;
-                    }/*for(i )*/
-                }/*if( tiBps == 8)*/
-                else
-                    if(tiBps == 12)/* CINEMA file */
-                    {
-                        step = 9;
-
-                        for(i = 0; i < ssize; i += step)
-                        {
-                            if((index < imgsize)&&(index+1 < imgsize))
-                            {
-                                image->comps[0].data[index]   = ( dat8[i+0]<<4 )        |(dat8[i+1]>>4);
-                                image->comps[1].data[index]   = ((dat8[i+1]& 0x0f)<< 8) | dat8[i+2];
-
-                                image->comps[2].data[index]   = ( dat8[i+3]<<4)         |(dat8[i+4]>>4);
-                                image->comps[0].data[index+1] = ((dat8[i+4]& 0x0f)<< 8) | dat8[i+5];
-
-                                image->comps[1].data[index+1] = ( dat8[i+6] <<4)        |(dat8[i+7]>>4);
-                                image->comps[2].data[index+1] = ((dat8[i+7]& 0x0f)<< 8) | dat8[i+8];
-
-                                index += 2;
-                            }
-                            else
-                                break;
-                        }/*for(i )*/
-                    }
-        }/*for(strip = 0; )*/
-
-        _TIFFfree(buf);
-        TIFFClose(tif);
-
-        return image;
-    }/*RGB(A)*/
-
-    if(tiPhoto == PHOTOMETRIC_MINISBLACK) /* GRAY(A) */
-    {
-        numcomps = 1 + has_alpha;
-        color_space = OPJ_CLRSPC_GRAY;
-
-        for(j = 0; j < numcomps; ++j)
-        {
-            cmptparm[j].prec = tiBps;
-            cmptparm[j].bpp = tiBps;
-            cmptparm[j].dx = (OPJ_UINT32)subsampling_dx;
-            cmptparm[j].dy = (OPJ_UINT32)subsampling_dy;
-            cmptparm[j].w = (OPJ_UINT32)w;
-            cmptparm[j].h = (OPJ_UINT32)h;
-        }
-#ifdef USETILEMODE
-        image = opj_image_tile_create(numcomps,&cmptparm[0],color_space);
-#else
-        image = opj_image_create((OPJ_UINT32)numcomps, &cmptparm[0], color_space);
-#endif
-
-        if(!image)
-        {
-            TIFFClose(tif);
-            return NULL;
-        }
-        /* set image offset and reference grid
-*/
-        image->x0 = (OPJ_UINT32)parameters->image_offset_x0;
-        image->y0 = (OPJ_UINT32)parameters->image_offset_y0;
-        image->x1 =    !image->x0 ? (OPJ_UINT32)(w - 1) * (OPJ_UINT32)subsampling_dx + 1 :
-                                 image->x0 + (OPJ_UINT32)(w - 1) * (OPJ_UINT32)subsampling_dx + 1;
-        image->y1 =    !image->y0 ? (OPJ_UINT32)(h - 1) * (OPJ_UINT32)subsampling_dy + 1 :
-                                 image->y0 + (OPJ_UINT32)(h - 1) * (OPJ_UINT32)subsampling_dy + 1;
-
-        buf = _TIFFmalloc(TIFFStripSize(tif));
-
-        strip_size = TIFFStripSize(tif);
-        index = 0;
-        imgsize = (int)(image->comps[0].w * image->comps[0].h);
-        /* Read the Image components
-*/
-        for(strip = 0; strip < TIFFNumberOfStrips(tif); strip++)
-        {
-            unsigned char *dat8;
-            tsize_t i, ssize;
-            int step;
-
-            ssize = TIFFReadEncodedStrip(tif, strip, buf, strip_size);
-            dat8 = (unsigned char*)buf;
-
-            if(tiBps == 16)
-            {
-                step = 2 + has_alpha + has_alpha;
-
-                for(i = 0; i < ssize; i += step)
-                {
-                    if(index < imgsize)
-                    {
-                        image->comps[0].data[index] = ( dat8[i+1] << 8 ) | dat8[i+0];
-                        if(has_alpha)
-                            image->comps[1].data[index] = ( dat8[i+3] << 8 ) | dat8[i+2];
-                        index++;
-                    }
-                    else
-                        break;
-                }/*for(i )*/
-            }
-            else
-                if(tiBps == 8)
-                {
-                    step = 1 + has_alpha;
-
-                    for(i = 0; i < ssize; i += step)
-                    {
-                        if(index < imgsize)
-                        {
-                            image->comps[0].data[index] = dat8[i+0];
-                            if(has_alpha)
-                                image->comps[1].data[index] = dat8[i+1];
-                            index++;
-                        }
-                        else
-                            break;
-                    }/*for(i )*/
-                }
-        }/*for(strip = 0;*/
-
-        _TIFFfree(buf);
-        TIFFClose(tif);
-
-    }/*GRAY(A)*/
-
-    return image;
-
-}/* tiftoimage() */
-
-#endif /* OPJ_HAVE_LIBTIFF */
-
 /* -->> -->> -->> -->>
 
     RAW IMAGE FORMAT
diff --git a/src/bin/jp2/converttif.c b/src/bin/jp2/converttif.c
new file mode 100644 (file)
index 0000000..85fc2b9
--- /dev/null
@@ -0,0 +1,984 @@
+/*
+ * The copyright in this software is being made available under the 2-clauses
+ * BSD License, included below. This software may be subject to other third
+ * party and contributor rights, including patent rights, and no such rights
+ * are granted under this license.
+ *
+ * Copyright (c) 2002-2014, Universite catholique de Louvain (UCL), Belgium
+ * Copyright (c) 2002-2014, Professor Benoit Macq
+ * Copyright (c) 2001-2003, David Janssens
+ * Copyright (c) 2002-2003, Yannick Verschueren
+ * Copyright (c) 2003-2007, Francois-Olivier Devaux
+ * Copyright (c) 2003-2014, Antonin Descampe
+ * Copyright (c) 2005, Herve Drolon, FreeImage Team
+ * Copyright (c) 2006-2007, Parvatha Elangovan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "opj_apps_config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+#ifndef OPJ_HAVE_LIBTIFF
+# error OPJ_HAVE_LIBTIFF_NOT_DEFINED
+#endif /* OPJ_HAVE_LIBTIFF */
+
+#include <tiffio.h>
+#include "openjpeg.h"
+#include "convert.h"
+
+/* -->> -->> -->> -->>
+ TIFF IMAGE FORMAT
+ <<-- <<-- <<-- <<-- */
+
+int imagetotif(opj_image_t * image, const char *outfile)
+{
+       int width, height, imgsize;
+       int bps,index,adjust, sgnd;
+       int ushift, dshift, has_alpha, force16;
+       TIFF *tif;
+       tdata_t buf;
+       tstrip_t strip;
+       tsize_t strip_size;
+       
+       ushift = dshift = force16 = has_alpha = 0;
+       bps = (int)image->comps[0].prec;
+       
+       if(bps > 8 && bps < 16)
+       {
+               ushift = 16 - bps; dshift = bps - ushift;
+               bps = 16; force16 = 1;
+       }
+       
+       if(bps != 8 && bps != 16)
+       {
+               fprintf(stderr,"imagetotif: Bits=%d, Only 8 and 16 bits implemented\n",
+                                               bps);
+               fprintf(stderr,"\tAborting\n");
+               return 1;
+       }
+       tif = TIFFOpen(outfile, "wb");
+       
+       if (!tif)
+       {
+               fprintf(stderr, "imagetotif:failed to open %s for writing\n", outfile);
+               return 1;
+       }
+       sgnd = (int)image->comps[0].sgnd;
+       adjust = sgnd ? 1 << (image->comps[0].prec - 1) : 0;
+       
+       if(image->numcomps >= 3
+                && image->comps[0].dx == image->comps[1].dx
+                && image->comps[1].dx == image->comps[2].dx
+                && image->comps[0].dy == image->comps[1].dy
+                && image->comps[1].dy == image->comps[2].dy
+                && image->comps[0].prec == image->comps[1].prec
+                && image->comps[1].prec == image->comps[2].prec)
+       {
+               has_alpha = (image->numcomps == 4);
+               
+               width   = (int)image->comps[0].w;
+               height  = (int)image->comps[0].h;
+               imgsize = width * height ;
+               
+               TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, width);
+               TIFFSetField(tif, TIFFTAG_IMAGELENGTH, height);
+               TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 3 + has_alpha);
+               TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, bps);
+               TIFFSetField(tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
+               TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
+               TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
+               TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, 1);
+               strip_size = TIFFStripSize(tif);
+               buf = _TIFFmalloc(strip_size);
+               index=0;
+               
+               for(strip = 0; strip < TIFFNumberOfStrips(tif); strip++)
+               {
+                       unsigned char *dat8;
+                       tsize_t i, ssize, last_i = 0;
+                       int step, restx;
+                       ssize = TIFFStripSize(tif);
+                       dat8 = (unsigned char*)buf;
+                       
+                       if(bps == 8)
+                       {
+                               step = 3 + has_alpha;
+                               restx = step - 1;
+                               
+                               for(i=0; i < ssize - restx; i += step)
+                               {
+                                       int r, g, b, a = 0;
+                                       
+                                       if(index < imgsize)
+                                       {
+                                               r = image->comps[0].data[index];
+                                               g = image->comps[1].data[index];
+                                               b = image->comps[2].data[index];
+                                               if(has_alpha) a = image->comps[3].data[index];
+                                               
+                                               if(sgnd)
+                                               {
+                                                       r += adjust;
+                                                       g += adjust;
+                                                       b += adjust;
+                                                       if(has_alpha) a += adjust;
+                                               }
+                                               if(r > 255) r = 255; else if(r < 0) r = 0;
+                                               dat8[i+0] = (unsigned char)r ;
+                                               if(g > 255) g = 255; else if(g < 0) g = 0;
+                                               dat8[i+1] = (unsigned char)g ;
+                                               if(b > 255) b = 255; else if(b < 0) b = 0;
+                                               dat8[i+2] = (unsigned char)b ;
+                                               if(has_alpha)
+                                               {
+                                                       if(a > 255) a = 255; else if(a < 0) a = 0;
+                                                       dat8[i+3] = (unsigned char)a;
+                                               }
+                                               
+                                               index++;
+                                               last_i = i + step;
+                                       }
+                                       else
+                                               break;
+                               }/*for(i = 0;)*/
+                               
+                               if(last_i < ssize)
+                               {
+                                       for(i = last_i; i < ssize; i += step)
+                                       {
+                                               int r, g, b, a = 0;
+                                               
+                                               if(index < imgsize)
+                                               {
+                                                       r = image->comps[0].data[index];
+                                                       g = image->comps[1].data[index];
+                                                       b = image->comps[2].data[index];
+                                                       if(has_alpha) a = image->comps[3].data[index];
+                                                       
+                                                       if(sgnd)
+                                                       {
+                                                               r += adjust;
+                                                               g += adjust;
+                                                               b += adjust;
+                                                               if(has_alpha) a += adjust;
+                                                       }
+                                                       if(r > 255) r = 255; else if(r < 0) r = 0;
+                                                       if(g > 255) g = 255; else if(g < 0) g = 0;
+                                                       if(b > 255) b = 255; else if(b < 0) b = 0;
+                                                       
+                                                       dat8[i+0] = (unsigned char)r ;
+                                                       if(i+1 < ssize) dat8[i+1] = (unsigned char)g ;  else break;
+                                                       if(i+2 < ssize) dat8[i+2] = (unsigned char)b ;  else break;
+                                                       if(has_alpha)
+                                                       {
+                                                               if(a > 255) a = 255; else if(a < 0) a = 0;
+                                                               
+                                                               if(i+3 < ssize) dat8[i+3] = (unsigned char)a ;  else break;
+                                                       }
+                                                       index++;
+                                               }
+                                               else
+                                                       break;
+                                       }/*for(i)*/
+                               }/*if(last_i < ssize)*/
+                               
+                       }       /*if(bps == 8)*/
+                       else
+                               if(bps == 16)
+                               {
+                                       step = 6 + has_alpha + has_alpha;
+                                       restx = step - 1;
+                                       
+                                       for(i = 0; i < ssize - restx ; i += step)
+                                       {
+                                               int r, g, b, a = 0;
+                                               
+                                               if(index < imgsize)
+                                               {
+                                                       r = image->comps[0].data[index];
+                                                       g = image->comps[1].data[index];
+                                                       b = image->comps[2].data[index];
+                                                       if(has_alpha) a = image->comps[3].data[index];
+                                                       
+                                                       if(sgnd)
+                                                       {
+                                                               r += adjust;
+                                                               g += adjust;
+                                                               b += adjust;
+                                                               if(has_alpha) a += adjust;
+                                                       }
+                                                       if(force16)
+                                                       {
+                                                               r = (r<<ushift) + (r>>dshift);
+                                                               g = (g<<ushift) + (g>>dshift);
+                                                               b = (b<<ushift) + (b>>dshift);
+                                                               if(has_alpha) a = (a<<ushift) + (a>>dshift);
+                                                       }
+                                                       if(r > 65535) r = 65535; else if(r < 0) r = 0;
+                                                       if(g > 65535) g = 65535; else if(g < 0) g = 0;
+                                                       if(b > 65535) b = 65535; else if(b < 0) b = 0;
+                                                       
+                                                       dat8[i+0] =  (unsigned char)r;/*LSB*/
+                                                       dat8[i+1] = (unsigned char)(r >> 8);/*MSB*/
+                                                       dat8[i+2] =  (unsigned char)g;
+                                                       dat8[i+3] = (unsigned char)(g >> 8);
+                                                       dat8[i+4] =  (unsigned char)b;
+                                                       dat8[i+5] = (unsigned char)(b >> 8);
+                                                       if(has_alpha)
+                                                       {
+                                                               if(a > 65535) a = 65535; else if(a < 0) a = 0;
+                                                               dat8[i+6] =  (unsigned char)a;
+                                                               dat8[i+7] = (unsigned char)(a >> 8);
+                                                       }
+                                                       index++;
+                                                       last_i = i + step;
+                                               }
+                                               else
+                                                       break;
+                                       }/*for(i = 0;)*/
+                                       
+                                       if(last_i < ssize)
+                                       {
+                                               for(i = last_i ; i < ssize ; i += step)
+                                               {
+                                                       int r, g, b, a = 0;
+                                                       
+                                                       if(index < imgsize)
+                                                       {
+                                                               r = image->comps[0].data[index];
+                                                               g = image->comps[1].data[index];
+                                                               b = image->comps[2].data[index];
+                                                               if(has_alpha) a = image->comps[3].data[index];
+                                                               
+                                                               if(sgnd)
+                                                               {
+                                                                       r += adjust;
+                                                                       g += adjust;
+                                                                       b += adjust;
+                                                                       if(has_alpha) a += adjust;
+                                                               }
+                                                               if(force16)
+                                                               {
+                                                                       r = (r<<ushift) + (r>>dshift);
+                                                                       g = (g<<ushift) + (g>>dshift);
+                                                                       b = (b<<ushift) + (b>>dshift);
+                                                                       if(has_alpha) a = (a<<ushift) + (a>>dshift);
+                                                               }
+                                                               if(r > 65535) r = 65535; else if(r < 0) r = 0;
+                                                               if(g > 65535) g = 65535; else if(g < 0) g = 0;
+                                                               if(b > 65535) b = 65535; else if(b < 0) b = 0;
+                                                               
+                                                               dat8[i+0] = (unsigned char) r;/*LSB*/
+                                                               if(i+1 < ssize) dat8[i+1] = (unsigned char)(r >> 8);else break;/*MSB*/
+                                                               if(i+2 < ssize) dat8[i+2] = (unsigned char) g;      else break;
+                                                               if(i+3 < ssize) dat8[i+3] = (unsigned char)(g >> 8);else break;
+                                                               if(i+4 < ssize) dat8[i+4] = (unsigned char) b;      else break;
+                                                               if(i+5 < ssize) dat8[i+5] = (unsigned char)(b >> 8);else break;
+                                                               
+                                                               if(has_alpha)
+                                                               {
+                                                                       if(a > 65535) a = 65535; else if(a < 0) a = 0;
+                                                                       if(i+6 < ssize) dat8[i+6] = (unsigned char)a; else break;
+                                                                       if(i+7 < ssize) dat8[i+7] = (unsigned char)(a >> 8); else break;
+                                                               }
+                                                               index++;
+                                                       }
+                                                       else
+                                                               break;
+                                               }/*for(i)*/
+                                       }/*if(last_i < ssize)*/
+                                       
+                               }/*if(bps == 16)*/
+                       (void)TIFFWriteEncodedStrip(tif, strip, (void*)buf, strip_size);
+               }/*for(strip = 0; )*/
+               
+               _TIFFfree((void*)buf);
+               TIFFClose(tif);
+               
+               return 0;
+       }/*RGB(A)*/
+       
+       if(image->numcomps == 1 /* GRAY */
+                || (   image->numcomps == 2 /* GRAY_ALPHA */
+                                && image->comps[0].dx == image->comps[1].dx
+                                && image->comps[0].dy == image->comps[1].dy
+                                && image->comps[0].prec == image->comps[1].prec))
+       {
+               int step;
+               
+               has_alpha = (image->numcomps == 2);
+               
+               width   = (int)image->comps[0].w;
+               height  = (int)image->comps[0].h;
+               imgsize = width * height;
+               
+               /* Set tags */
+               TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, width);
+               TIFFSetField(tif, TIFFTAG_IMAGELENGTH, height);
+               TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 1 + has_alpha);
+               TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, bps);
+               TIFFSetField(tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
+               TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
+               TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK);
+               TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, 1);
+               
+               /* Get a buffer for the data */
+               strip_size = TIFFStripSize(tif);
+               buf = _TIFFmalloc(strip_size);
+               index = 0;
+               
+               for(strip = 0; strip < TIFFNumberOfStrips(tif); strip++)
+               {
+                       unsigned char *dat8;
+                       tsize_t i, ssize = TIFFStripSize(tif);
+                       dat8 = (unsigned char*)buf;
+                       
+                       if(bps == 8)
+                       {
+                               step = 1 + has_alpha;
+                               
+                               for(i=0; i < ssize; i += step)
+                               {
+                                       if(index < imgsize)
+                                       {
+                                               int r, a = 0;
+                                               
+                                               r = image->comps[0].data[index];
+                                               if(has_alpha) a = image->comps[1].data[index];
+                                               
+                                               if(sgnd)
+                                               {
+                                                       r += adjust;
+                                                       if(has_alpha) a += adjust;
+                                               }
+                                               if(r > 255) r = 255; else if(r < 0) r = 0;
+                                               dat8[i+0] = (unsigned char)r;
+                                               
+                                               if(has_alpha)
+                                               {
+                                                       if(a > 255) a = 255; else if(a < 0) a = 0;
+                                                       dat8[i+1] = (unsigned char)a;
+                                               }
+                                               index++;
+                                       }
+                                       else
+                                               break;
+          }/*for(i )*/
+                       }/*if(bps == 8*/
+                       else
+                               if(bps == 16)
+                               {
+                                       step = 2 + has_alpha + has_alpha;
+                                       
+                                       for(i=0; i < ssize; i += step)
+                                       {
+                                               if(index < imgsize)
+                                               {
+                                                       int r, a = 0;
+                                                       
+                                                       r = image->comps[0].data[index];
+                                                       if(has_alpha) a = image->comps[1].data[index];
+                                                       
+                                                       if(sgnd)
+                                                       {
+                                                               r += adjust;
+                                                               if(has_alpha) a += adjust;
+                                                       }
+                                                       if(force16)
+                                                       {
+                                                               r = (r<<ushift) + (r>>dshift);
+                                                               if(has_alpha) a = (a<<ushift) + (a>>dshift);
+                                                       }
+                                                       if(r > 65535) r = 65535; else if(r < 0) r = 0;
+                                                       dat8[i+0] = (unsigned char)r;/*LSB*/
+                                                       dat8[i+1] = (unsigned char)(r >> 8);/*MSB*/
+                                                       if(has_alpha)
+                                                       {
+                                                               if(a > 65535) a = 65535; else if(a < 0) a = 0;
+                                                               dat8[i+2] = (unsigned char)a;
+                                                               dat8[i+3] = (unsigned char)(a >> 8);
+                                                       }
+                                                       index++;
+                                               }/*if(index < imgsize)*/
+                                               else
+                                                       break;
+                                       }/*for(i )*/
+                               }
+                       (void)TIFFWriteEncodedStrip(tif, strip, (void*)buf, strip_size);
+               }/*for(strip*/
+               
+               _TIFFfree(buf);
+               TIFFClose(tif);
+               
+               return 0;
+       }
+       
+       TIFFClose(tif);
+       
+       fprintf(stderr,"imagetotif: Bad color format.\n"
+                                       "\tOnly RGB(A) and GRAY(A) has been implemented\n");
+       fprintf(stderr,"\tFOUND: numcomps(%d)\n\tAborting\n",
+                                       image->numcomps);
+       
+       return 1;
+}/* imagetotif() */
+
+typedef void (* tif_Xto32s)(const OPJ_BYTE* pSrc, OPJ_INT32* pDst, OPJ_SIZE_T length);
+
+static void tif_1uto32s(const OPJ_BYTE* pSrc, OPJ_INT32* pDst, OPJ_SIZE_T length)
+{
+       OPJ_SIZE_T i;
+       for (i = 0; i < (length & -(OPJ_SIZE_T)8U); i+=8U) {
+               OPJ_UINT8 val = *pSrc++;
+               pDst[i+0] =  val >> 7;
+               pDst[i+1] = (val >> 6) & 0x1U;
+               pDst[i+2] = (val >> 5) & 0x1U;
+               pDst[i+3] = (val >> 4) & 0x1U;
+               pDst[i+4] = (val >> 3) & 0x1U;
+               pDst[i+5] = (val >> 2) & 0x1U;
+               pDst[i+6] = (val >> 1) & 0x1U;
+               pDst[i+7] = val & 0x1U;
+       }
+       if (length & 7U) {
+               OPJ_UINT8 val = *pSrc++;
+               length = length & 7U;
+               pDst[i+0] =  val >> 7;
+               
+               if (length > 1U) {
+                       pDst[i+1] = (val >> 6) & 0x1U;
+                       if (length > 2U) {
+                               pDst[i+2] = (val >> 5) & 0x1U;
+                               if (length > 3U) {
+                                       pDst[i+3] = (val >> 4) & 0x1U;
+                                       if (length > 4U) {
+                                               pDst[i+4] = (val >> 3) & 0x1U;
+                                               if (length > 5U) {
+                                                       pDst[i+5] = (val >> 2) & 0x1U;
+                                                       if (length > 6U) {
+                                                               pDst[i+6] = (val >> 1) & 0x1U;
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               }
+       }
+}
+static void tif_2uto32s(const OPJ_BYTE* pSrc, OPJ_INT32* pDst, OPJ_SIZE_T length)
+{
+       OPJ_SIZE_T i;
+       for (i = 0; i < (length & -(OPJ_SIZE_T)4U); i+=4U) {
+               OPJ_UINT8 val = *pSrc++;
+               pDst[i+0] =  val >> 6;
+               pDst[i+1] = (val >> 4) & 0x3U;
+               pDst[i+2] = (val >> 2) & 0x3U;
+               pDst[i+3] = val & 0x3U;
+       }
+       if (length & 3U) {
+               OPJ_UINT8 val = *pSrc++;
+               length = length & 3U;
+               pDst[i+0] =  val >> 6;
+               
+               if (length > 1U) {
+                       pDst[i+1] = (val >> 4) & 0x3U;
+                       if (length > 2U) {
+                               pDst[i+2] = (val >> 2) & 0x3U;
+                               
+                       }
+               }
+       }
+}
+static void tif_4uto32s(const OPJ_BYTE* pSrc, OPJ_INT32* pDst, OPJ_SIZE_T length)
+{
+       OPJ_SIZE_T i;
+       for (i = 0; i < (length & -(OPJ_SIZE_T)2U); i+=2U) {
+               OPJ_UINT8 val = *pSrc++;
+               pDst[i+0] = val >> 4;
+               pDst[i+1] = val & 0xFU;
+       }
+       if (length & 1U) {
+               OPJ_UINT8 val = *pSrc++;
+               pDst[i+0] = val >> 4;
+       }
+}
+static void tif_6uto32s(const OPJ_BYTE* pSrc, OPJ_INT32* pDst, OPJ_SIZE_T length)
+{
+       OPJ_SIZE_T i;
+       for (i = 0; i < (length & -(OPJ_SIZE_T)4U); i+=4U) {
+               OPJ_UINT8 val0 = *pSrc++;
+               OPJ_UINT8 val1 = *pSrc++;
+               OPJ_UINT8 val2 = *pSrc++;
+               pDst[i+0] = val0 >> 2;
+               pDst[i+1] = ((val0 & 0x3U) << 4) | (val1 >> 4);
+               pDst[i+2] = ((val1 & 0xFU) << 2) | (val2 >> 6);
+               pDst[i+3] = val2 & 0x3FU;
+               
+       }
+       if (length & 3U) {
+               OPJ_UINT8 val0 = *pSrc++;
+               length = length & 3U;
+               pDst[i+0] =  val0 >> 2;
+               
+               if (length > 1U) {
+                       OPJ_UINT8 val1 = *pSrc++;
+                       pDst[i+1] = ((val0 & 0x3U) << 4) | (val1 >> 4);
+                       if (length > 2U) {
+                               OPJ_UINT8 val2 = *pSrc++;
+                               pDst[i+2] = ((val1 & 0xFU) << 2) | (val2 >> 6);
+                       }
+               }
+       }
+}
+static void tif_8uto32s(const OPJ_BYTE* pSrc, OPJ_INT32* pDst, OPJ_SIZE_T length)
+{
+       OPJ_SIZE_T i;
+       for (i = 0; i < length; ++i) {
+               pDst[i] = pSrc[i];
+       }
+}
+static void tif_10uto32s(const OPJ_BYTE* pSrc, OPJ_INT32* pDst, OPJ_SIZE_T length)
+{
+       OPJ_SIZE_T i;
+       for (i = 0; i < (length & -(OPJ_SIZE_T)4U); i+=4U) {
+               OPJ_INT32 val0 = *pSrc++;
+               OPJ_INT32 val1 = *pSrc++;
+               OPJ_INT32 val2 = *pSrc++;
+               OPJ_INT32 val3 = *pSrc++;
+               OPJ_INT32 val4 = *pSrc++;
+               
+               pDst[i+0] = (val0 << 2) | (val1 >> 6);
+               pDst[i+1] = ((val1 & 0x3FU) << 4) | (val2 >> 4);
+               pDst[i+2] = ((val2 & 0xFU) << 6) | (val3 >> 2);
+               pDst[i+3] = ((val3 & 0x3U) << 8) | val4;
+               
+       }
+       if (length & 3U) {
+               OPJ_INT32 val0 = *pSrc++;
+               OPJ_INT32 val1 = *pSrc++;
+               length = length & 3U;
+               pDst[i+0] = (val0 << 2) | (val1 >> 6);
+               
+               if (length > 1U) {
+                       OPJ_INT32 val2 = *pSrc++;
+                       pDst[i+1] = ((val1 & 0x3FU) << 4) | (val2 >> 4);
+                       if (length > 2U) {
+                               OPJ_INT32 val3 = *pSrc++;
+                               pDst[i+2] = ((val2 & 0xFU) << 6) | (val3 >> 2);
+                       }
+               }
+       }
+}
+static void tif_12uto32s(const OPJ_BYTE* pSrc, OPJ_INT32* pDst, OPJ_SIZE_T length)
+{
+       OPJ_SIZE_T i;
+       for (i = 0; i < (length & -(OPJ_SIZE_T)2U); i+=2U) {
+               OPJ_INT32 val0 = *pSrc++;
+               OPJ_INT32 val1 = *pSrc++;
+               OPJ_INT32 val2 = *pSrc++;
+
+               pDst[i+0] = (val0 << 4) | (val1 >> 4);
+               pDst[i+1] = ((val1 & 0xFU) << 8) | val2;
+       }
+       if (length & 1U) {
+               OPJ_INT32 val0 = *pSrc++;
+               OPJ_INT32 val1 = *pSrc++;
+               pDst[i+0] = (val0 << 4) | (val1 >> 4);
+       }
+}
+static void tif_14uto32s(const OPJ_BYTE* pSrc, OPJ_INT32* pDst, OPJ_SIZE_T length)
+{
+       OPJ_SIZE_T i;
+       for (i = 0; i < (length & -(OPJ_SIZE_T)4U); i+=4U) {
+               OPJ_INT32 val0 = *pSrc++;
+               OPJ_INT32 val1 = *pSrc++;
+               OPJ_INT32 val2 = *pSrc++;
+               OPJ_INT32 val3 = *pSrc++;
+               OPJ_INT32 val4 = *pSrc++;
+               OPJ_INT32 val5 = *pSrc++;
+               OPJ_INT32 val6 = *pSrc++;
+               
+               pDst[i+0] = (val0 << 6) | (val1 >> 2);
+               pDst[i+1] = ((val1 & 0x3U) << 12) | (val2 << 4) | (val3 >> 4);
+               pDst[i+2] = ((val3 & 0xFU) << 10) | (val4 << 2) | (val5 >> 6);
+               pDst[i+3] = ((val5 & 0x3FU) << 8) | val6;
+               
+       }
+       if (length & 3U) {
+               OPJ_INT32 val0 = *pSrc++;
+               OPJ_INT32 val1 = *pSrc++;
+               length = length & 3U;
+               pDst[i+0] = (val0 << 6) | (val1 >> 2);
+               
+               if (length > 1U) {
+                       OPJ_INT32 val2 = *pSrc++;
+                       OPJ_INT32 val3 = *pSrc++;
+                       pDst[i+1] = ((val1 & 0x3U) << 12) | (val2 << 4) | (val3 >> 4);
+                       if (length > 2U) {
+                               OPJ_INT32 val4 = *pSrc++;
+                               OPJ_INT32 val5 = *pSrc++;
+                               pDst[i+2] = ((val3 & 0xFU) << 10) | (val4 << 2) | (val5 >> 6);
+                       }
+               }
+       }
+}
+#if 0
+static void tif_16uto32s(const OPJ_BYTE* pSrc, OPJ_INT32* pDst, OPJ_SIZE_T length)
+{
+       OPJ_SIZE_T i;
+       for (i = 0; i < length; i++) {
+               OPJ_INT32 val0 = *pSrc++;
+               OPJ_INT32 val1 = *pSrc++;
+#ifdef OPJ_BIG_ENDIAN
+               pDst[i] = (val0 << 8) | val1;
+#else
+               pDst[i] = (val1 << 8) | val0;
+#endif
+       }
+}
+#else
+/* seems that libtiff decodes this to machine endianness */
+static void tif_16uto32s(const OPJ_UINT16* pSrc, OPJ_INT32* pDst, OPJ_SIZE_T length)
+{
+       OPJ_SIZE_T i;
+       for (i = 0; i < length; i++) {
+               pDst[i] = pSrc[i];
+       }
+}
+#endif
+
+typedef void (* convert_32s_CXPX)(const OPJ_INT32* pSrc, OPJ_INT32* const* pDst, OPJ_SIZE_T length);
+static void convert_32s_C1P1(const OPJ_INT32* pSrc, OPJ_INT32* const* pDst, OPJ_SIZE_T length)
+{
+       memcpy(pDst[0], pSrc, length * sizeof(OPJ_INT32));
+}
+static void convert_32s_C2P2(const OPJ_INT32* pSrc, OPJ_INT32* const* pDst, OPJ_SIZE_T length)
+{
+       OPJ_SIZE_T i;
+       OPJ_INT32* pDst0 = pDst[0];
+       OPJ_INT32* pDst1 = pDst[1];
+       
+       for (i = 0; i < length; i++) {
+               pDst0[i] = pSrc[2*i+0];
+               pDst1[i] = pSrc[2*i+1];
+       }
+}
+static void convert_32s_C3P3(const OPJ_INT32* pSrc, OPJ_INT32* const* pDst, OPJ_SIZE_T length)
+{
+       OPJ_SIZE_T i;
+       OPJ_INT32* pDst0 = pDst[0];
+       OPJ_INT32* pDst1 = pDst[1];
+       OPJ_INT32* pDst2 = pDst[2];
+       
+       for (i = 0; i < length; i++) {
+               pDst0[i] = pSrc[3*i+0];
+               pDst1[i] = pSrc[3*i+1];
+               pDst2[i] = pSrc[3*i+2];
+       }
+}
+static void convert_32s_C4P4(const OPJ_INT32* pSrc, OPJ_INT32* const* pDst, OPJ_SIZE_T length)
+{
+       OPJ_SIZE_T i;
+       OPJ_INT32* pDst0 = pDst[0];
+       OPJ_INT32* pDst1 = pDst[1];
+       OPJ_INT32* pDst2 = pDst[2];
+       OPJ_INT32* pDst3 = pDst[3];
+       
+       for (i = 0; i < length; i++) {
+               pDst0[i] = pSrc[4*i+0];
+               pDst1[i] = pSrc[4*i+1];
+               pDst2[i] = pSrc[4*i+2];
+               pDst3[i] = pSrc[4*i+3];
+       }
+}
+
+
+/*
+ * libtiff/tif_getimage.c : 1,2,4,8,16 bitspersample accepted
+ * CINEMA                 : 12 bit precision
+ */
+opj_image_t* tiftoimage(const char *filename, opj_cparameters_t *parameters)
+{
+       int subsampling_dx = parameters->subsampling_dx;
+       int subsampling_dy = parameters->subsampling_dy;
+       TIFF *tif;
+       tdata_t buf;
+       tstrip_t strip;
+       tsize_t strip_size;
+       int j, currentPlane, numcomps = 0, w, h;
+       OPJ_COLOR_SPACE color_space;
+       opj_image_cmptparm_t cmptparm[4]; /* RGBA */
+       opj_image_t *image = NULL;
+       int has_alpha = 0;
+       unsigned short tiBps, tiPhoto, tiSf, tiSpp, tiPC;
+       unsigned int tiWidth, tiHeight;
+       OPJ_BOOL is_cinema = OPJ_IS_CINEMA(parameters->rsiz);
+       tif_Xto32s cvtTifTo32s = NULL;
+       convert_32s_CXPX cvtCxToPx = NULL;
+       OPJ_INT32* buffer32s = NULL;
+       OPJ_INT32* planes[4];
+       OPJ_SIZE_T rowStride;
+       
+       tif = TIFFOpen(filename, "r");
+       
+       if(!tif)
+       {
+               fprintf(stderr, "tiftoimage:Failed to open %s for reading\n", filename);
+               return 0;
+       }
+       tiBps = tiPhoto = tiSf = tiSpp = tiPC = 0;
+       tiWidth = tiHeight = 0;
+       
+       TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &tiWidth);
+       TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &tiHeight);
+       TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &tiBps);
+       TIFFGetField(tif, TIFFTAG_SAMPLEFORMAT, &tiSf);
+       TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &tiSpp);
+       TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &tiPhoto);
+       TIFFGetField(tif, TIFFTAG_PLANARCONFIG, &tiPC);
+       w= (int)tiWidth;
+       h= (int)tiHeight;
+       
+       if((tiBps > 16U) || ((tiBps != 1U) && (tiBps & 1U))) tiBps = 0U;
+       if(tiPhoto != PHOTOMETRIC_MINISBLACK && tiPhoto != PHOTOMETRIC_RGB) tiPhoto = 0;
+       
+       if( !tiBps || !tiPhoto)
+       {
+               if( !tiBps)
+                       fprintf(stderr,"tiftoimage: Bits=%d, Only 1, 2, 4, 6, 8, 10, 12, 14 and 16 bits implemented\n",tiBps);
+               else
+                       if( !tiPhoto)
+                               fprintf(stderr,"tiftoimage: Bad color format %d.\n\tOnly RGB(A)"
+                                                               " and GRAY(A) has been implemented\n",(int) tiPhoto);
+               
+               fprintf(stderr,"\tAborting\n");
+               TIFFClose(tif);
+               return NULL;
+       }
+       
+       switch (tiBps) {
+               case 1:
+                       cvtTifTo32s = tif_1uto32s;
+                       break;
+               case 2:
+                       cvtTifTo32s = tif_2uto32s;
+                       break;
+               case 4:
+                       cvtTifTo32s = tif_4uto32s;
+                       break;
+               case 6:
+                       cvtTifTo32s = tif_6uto32s;
+                       break;
+               case 8:
+                       cvtTifTo32s = tif_8uto32s;
+                       break;
+               case 10:
+                       cvtTifTo32s = tif_10uto32s;
+                       break;
+               case 12:
+                       cvtTifTo32s = tif_12uto32s;
+                       break;
+               case 14:
+                       cvtTifTo32s = tif_14uto32s;
+                       break;
+               case 16:
+                       cvtTifTo32s = (tif_Xto32s)tif_16uto32s;
+                       break;
+               default:
+                       /* never here */
+                       break;
+       }
+       
+       {/* From: tiff-4.0.x/libtiff/tif_getimage.c : */
+               uint16* sampleinfo;
+               uint16 extrasamples;
+               
+               TIFFGetFieldDefaulted(tif, TIFFTAG_EXTRASAMPLES,
+                                                                                                       &extrasamples, &sampleinfo);
+               
+               if(extrasamples >= 1)
+               {
+                       switch(sampleinfo[0])
+                       {
+                               case EXTRASAMPLE_UNSPECIFIED:
+                                       /* Workaround for some images without correct info about alpha channel
+                                        */
+                                       if(tiSpp > 3)
+                                               has_alpha = 1;
+                                       break;
+                                       
+                               case EXTRASAMPLE_ASSOCALPHA: /* data pre-multiplied */
+                               case EXTRASAMPLE_UNASSALPHA: /* data not pre-multiplied */
+                                       has_alpha = 1;
+                                       break;
+                       }
+               }
+               else /* extrasamples == 0 */
+                       if(tiSpp == 4 || tiSpp == 2) has_alpha = 1;
+       }
+       
+       /* initialize image components
+        */
+       memset(&cmptparm[0], 0, 4 * sizeof(opj_image_cmptparm_t));
+       
+       if ((tiPhoto == PHOTOMETRIC_RGB) && (is_cinema) && (tiBps != 12U)) {
+               fprintf(stdout,"WARNING:\n"
+                                               "Input image bitdepth is %d bits\n"
+                                               "TIF conversion has automatically rescaled to 12-bits\n"
+                                               "to comply with cinema profiles.\n",
+                                               tiBps);
+       } else {
+               is_cinema = 0U;
+       }
+       
+       if(tiPhoto == PHOTOMETRIC_RGB) /* RGB(A) */
+       {
+               numcomps = 3 + has_alpha;
+               color_space = OPJ_CLRSPC_SRGB;
+       }
+       else if (tiPhoto == PHOTOMETRIC_MINISBLACK) /* GRAY(A) */
+       {
+               numcomps = 1 + has_alpha;
+               color_space = OPJ_CLRSPC_GRAY;
+       }
+       
+       switch (numcomps) {
+               case 1:
+                       cvtCxToPx = convert_32s_C1P1;
+                       break;
+               case 2:
+                       cvtCxToPx = convert_32s_C2P2;
+                       break;
+               case 3:
+                       cvtCxToPx = convert_32s_C3P3;
+                       break;
+               case 4:
+                       cvtCxToPx = convert_32s_C4P4;
+                       break;
+  default:
+                       /* never here */
+                       break;
+       }
+       if (tiPC == PLANARCONFIG_SEPARATE) {
+               cvtCxToPx = convert_32s_C1P1; /* override */
+               tiSpp = 1U; /* consider only one sample per plane */
+       }
+
+       for(j = 0; j < numcomps; j++)
+       {
+               cmptparm[j].prec = tiBps;
+               cmptparm[j].bpp = tiBps;
+               cmptparm[j].dx = (OPJ_UINT32)subsampling_dx;
+               cmptparm[j].dy = (OPJ_UINT32)subsampling_dy;
+               cmptparm[j].w = (OPJ_UINT32)w;
+               cmptparm[j].h = (OPJ_UINT32)h;
+       }
+               
+       image = opj_image_create((OPJ_UINT32)numcomps, &cmptparm[0], color_space);
+       if(!image)
+       {
+               TIFFClose(tif);
+               return NULL;
+       }
+       /* set image offset and reference grid */
+       image->x0 = (OPJ_UINT32)parameters->image_offset_x0;
+       image->y0 = (OPJ_UINT32)parameters->image_offset_y0;
+       image->x1 =     !image->x0 ? (OPJ_UINT32)(w - 1) * (OPJ_UINT32)subsampling_dx + 1 :
+       image->x0 + (OPJ_UINT32)(w - 1) * (OPJ_UINT32)subsampling_dx + 1;
+       image->y1 =     !image->y0 ? (OPJ_UINT32)(h - 1) * (OPJ_UINT32)subsampling_dy + 1 :
+       image->y0 + (OPJ_UINT32)(h - 1) * (OPJ_UINT32)subsampling_dy + 1;
+
+       for(j = 0; j < numcomps; j++)
+       {
+               planes[j] = image->comps[j].data;
+               if (has_alpha) {
+                       planes[j] = image->comps[j].data;
+               }
+       }
+               
+       strip_size = TIFFStripSize(tif);
+       
+       buf = _TIFFmalloc(strip_size);
+       if (buf == NULL) {
+               TIFFClose(tif);
+               opj_image_destroy(image);
+               return NULL;
+       }
+       rowStride = ((OPJ_SIZE_T)w * tiSpp * tiBps + 7U) / 8U;
+       buffer32s = malloc((OPJ_SIZE_T)w * tiSpp * sizeof(OPJ_INT32));
+       if (buffer32s == NULL) {
+               _TIFFfree(buf);
+               TIFFClose(tif);
+               opj_image_destroy(image);
+               return NULL;
+       }
+       
+       strip = 0;
+       currentPlane = 0;
+       do
+       {
+               planes[0] = image->comps[currentPlane].data; /* to manage planar data */
+               h= (int)tiHeight;
+               /* Read the Image components */
+               for(; (h > 0) && (strip < TIFFNumberOfStrips(tif)); strip++)
+               {
+                               const OPJ_UINT8 *dat8;
+                               tsize_t ssize;
+                               
+                               ssize = TIFFReadEncodedStrip(tif, strip, buf, strip_size);
+                               dat8 = (const OPJ_UINT8*)buf;
+                               
+                               while (ssize >= rowStride) {
+                                       cvtTifTo32s(dat8, buffer32s, w * tiSpp);
+                                       cvtCxToPx(buffer32s, planes, w);
+                                       planes[0] += w;
+                                       planes[1] += w;
+                                       planes[2] += w;
+                                       planes[3] += w;
+                                       dat8  += rowStride;
+                                       ssize -= rowStride;
+                                       h--;
+                               }
+               }
+               currentPlane++;
+       } while ((tiPC == PLANARCONFIG_SEPARATE) && (currentPlane < numcomps));
+       
+       free(buffer32s);
+       _TIFFfree(buf);
+       TIFFClose(tif);
+       
+       if (is_cinema) {
+               for (j=0; j < numcomps; ++j) {
+                       scale_component(&(image->comps[j]), 12);
+               }
+               
+       }
+       return image;
+
+}/* tiftoimage() */
+
index 64f63e837f676ae47f26e85fe3237a737c73493d..ee39de8e7c693184e209f16830518d10ca7a8656 100644 (file)
@@ -13,6 +13,7 @@ include_directories(
 # First thing define the common source:
 set(compare_images_SRCS compare_images.c
   ${OPENJPEG_SOURCE_DIR}/src/bin/jp2/convert.c
+  ${OPENJPEG_SOURCE_DIR}/src/bin/jp2/converttif.c
   ${OPENJPEG_SOURCE_DIR}/src/bin/common/opj_getopt.c
   )