void vixo_clumpFreq::init(string fileName,float baseValue,float noiseAmp,int noiseFreq) { this->baseValue=baseValue; this->noiseAmp=noiseAmp; this->noiseFreq=noiseFreq; this->filename=fileName; if(fileName!=""||this->baseValue!=0) { hasEffect=true; } else hasEffect=false; if(fileName!="") { TIFF* tif = TIFFOpen(fileName.c_str(), "r"); if (tif) { size_t npixels; TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width); TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height); npixels = width * height; pixels.resize(npixels); TIFFReadRGBAImage(tif, width, height, &pixels[0], 0); //abgr TIFFClose(tif); } } }
/** Function for loading TIFF images. Function for loading TIFF images. Supports RGB (8 bits) and grayscale (8 and 16 bits) images, 2D and 3D. Alternative version with simpler code. */ VglImage* vglLoadTiffAlt(char* inFilename) { TIFF* tif; VglImage* img; uint16 pageNumber, numberPages, subfileType; tif = TIFFOpen(inFilename, "r"); if (tif == NULL){ fprintf(stderr, "%s:%s: Error: File %s not found.\n", __FILE__, __FUNCTION__, inFilename); return NULL; } int width = tif_Width(tif); int height = tif_Height(tif); int is3d = tif_Is3d(tif); int layers = tif_Layers(tif); int depth = tif_BytesPerPixel(tif); // bytes per pixel int iplDepth = convertDepthTiffToVgl(depth); // depth \in {IPL_DEPTH_8U, ...} int nChannels = tif_nChannels(tif); // number of channels if (is3d) { img = vglCreate3dImage(cvSize(width,height), iplDepth, nChannels, layers, 0); } else { img = vglCreateImage(cvSize(width,height), iplDepth, nChannels); } char* imageData = img->getImageData(); int widthStep = img->getWidthStep(); char* buffer = (char*) tif_Malloc(tif); int pixelsPerLine = img->getWidth()*img->getNChannels(); int bytesPerLine = pixelsPerLine*depth; int i = 0; int offset = 0; do { /* for(int i = 0; i < height; i++) { printf("i = %d\n", i); TIFFReadScanline(tif, buffer, i); memcpy(imageData + offset, buffer, bytesPerLine); offset += widthStep; } */ TIFFReadRGBAImage(tif, width, height, (uint32*) buffer, 0); memcpy(imageData + offset, buffer, widthStep*height); offset += widthStep + height; } while(TIFFReadDirectory(tif)); TIFFClose(tif); vglSetContext(img, VGL_RAM_CONTEXT); return img; }
/* This routine reads in a TIFF image from "filename" and returns the number of columns and number of rows as arguments. The return value of the function is a pointer to the image data, which is in ABGR format, with 8 bits per color. The function returns a NULL value if it is unable to read in the data. */ uint32 *tiff_read(char filename[], uint32 *nrow, uint32 *ncol) { TIFF* tif = TIFFOpen(filename, "r"); *ncol = *nrow = 0; if (tif) { uint32 w, h; size_t npixels; uint32 *raster; TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &w); TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &h); npixels = w * h; raster = (uint32*) _TIFFmalloc(npixels * sizeof (uint32)); if (raster != NULL) { if (TIFFReadRGBAImage(tif, w, h, raster, 0)) { *ncol = w; *nrow = h; TIFFClose(tif); return(raster); } else { TIFFClose(tif); return(NULL); } } else { TIFFClose(tif); return(NULL); } } else { return(NULL); } }
timg_t *timg_readtiff(const char *fname) { TIFF *tif = TIFFOpen(fname, "r"); uint32_t width=0, height=0; TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width); TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height); uint32_t *raster = (uint32_t*)_TIFFmalloc(width*height*sizeof(uint32_t)); if(TIFFReadRGBAImage(tif, width, height, raster, 0) == 0) { fprintf(stderr, "An error occurred reading the TIFF file.\n"); exit(1); } timg_t *img = timg_create(height, width); int i; for(i=0; i<height*width; ++i) { img->pixels[i].r = (uint8_t)TIFFGetR(raster[i]); img->pixels[i].g = (uint8_t)TIFFGetG(raster[i]); img->pixels[i].b = (uint8_t)TIFFGetB(raster[i]); img->pixels[i].a = (uint8_t)TIFFGetA(raster[i]); } _TIFFfree(raster); TIFFClose(tif); return img; }
_declspec (dllexport) int readImage(TIFF* tif, // TIFF handle - IN const int directory, // page ordinal number - IN uint8_t* redvals) // OUT, caller allocates memory { TIFFSetDirectory(tif, directory); int err = 0; uint32_t w, h; size_t npixels; TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &w); TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &h); //TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, bits); npixels = w * h; uint32_t* raster = (uint32_t*) _TIFFmalloc(npixels * sizeof (uint32_t)); if (raster != NULL) { err = TIFFReadRGBAImage(tif, w, h, raster, 1); if (err != 1) { return err; } uint32_t* pFrom = raster; uint8_t* pTo = redvals; for (int i = 0; i < npixels; i++, ++pFrom) { *pTo++ = (uint8_t) TIFFGetR(*pFrom); } } _TIFFfree(raster); return err; }
int ImageTiff( char *NomFichierTiff, int * largpx, int * hautpx, int * nbc1px, unsigned char ** image ) //Construction d'image[largpx][hautpx][nbc1px] couleur RGB //Retourne un code d'erreur : 0 si pas d'erreur { *nbc1px = 3; //3 octets pour RGB *image = NULL; //unsigned char image[256][256][3]; //uint32 l, h; int i, j; size_t npixels; uint32* raster; //chargement de l'image a partir d'un fichier.tiff printf(" fichier %s \n",NomFichierTiff); TIFF* tif = TIFFOpen(NomFichierTiff, "r"); if (tif) { TIFFGetField( tif, TIFFTAG_IMAGEWIDTH, largpx ); TIFFGetField( tif, TIFFTAG_IMAGELENGTH, hautpx ); *image = ( unsigned char *)malloc( sizeof(unsigned char)*(*largpx) * (*hautpx) * (*nbc1px)); if( *image == NULL ) return 1; npixels = (*largpx) * (*hautpx); raster = (uint32*) _TIFFmalloc( npixels * sizeof(uint32) ); if (raster != NULL) { // lecture de l'image if( TIFFReadRGBAImage(tif, *largpx, *hautpx, raster, 1) ) { // transfert de l'image vers le tableau 'image' int k=0; for (i=0; i<*largpx; i++) for (j=0; j<*hautpx; j++) { (*image)[k++]=((unsigned char *)raster)[i*(*hautpx)*4+j*4+0]; (*image)[k++]=((unsigned char *)raster)[i*(*hautpx)*4+j*4+1]; (*image)[k++]=((unsigned char *)raster)[i*(*hautpx)*4+j*4+2]; } } else { printf("Erreur de chargement du fichier %s\n", NomFichierTiff); return 2; } _TIFFfree(raster); } TIFFClose(tif); } printf("Fichier Tiff image %s \n", NomFichierTiff); printf( " largeur pixels=%d hauteur pixels= %d bytes par pixel= %d \n", largpx,hautpx, nbc1px); return 0; }
static int tiffcvt(TIFF* in, TIFF* out) { uint32 width, height; /* image width & height */ uint32* raster; /* retrieve RGBA image */ uint16 shortv; float floatv; char *stringv; uint32 longv; TIFFGetField(in, TIFFTAG_IMAGEWIDTH, &width); TIFFGetField(in, TIFFTAG_IMAGELENGTH, &height); raster = (uint32*)_TIFFmalloc(width * height * sizeof (uint32)); if (raster == 0) { TIFFError(TIFFFileName(in), "No space for raster buffer"); return (0); } if (!TIFFReadRGBAImage(in, width, height, raster, 0)) { _TIFFfree(raster); return (0); } CopyField(TIFFTAG_SUBFILETYPE, longv); TIFFSetField(out, TIFFTAG_IMAGEWIDTH, width); TIFFSetField(out, TIFFTAG_IMAGELENGTH, height); TIFFSetField(out, TIFFTAG_BITSPERSAMPLE, 8); TIFFSetField(out, TIFFTAG_COMPRESSION, compression); TIFFSetField(out, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_YCBCR); if (compression == COMPRESSION_JPEG) TIFFSetField(out, TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RAW); CopyField(TIFFTAG_FILLORDER, shortv); TIFFSetField(out, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT); TIFFSetField(out, TIFFTAG_SAMPLESPERPIXEL, 3); CopyField(TIFFTAG_XRESOLUTION, floatv); CopyField(TIFFTAG_YRESOLUTION, floatv); CopyField(TIFFTAG_RESOLUTIONUNIT, shortv); TIFFSetField(out, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); { char buf[2048]; char *cp = strrchr(TIFFFileName(in), '/'); sprintf(buf, "YCbCr conversion of %s", cp ? cp+1 : TIFFFileName(in)); TIFFSetField(out, TIFFTAG_IMAGEDESCRIPTION, buf); } TIFFSetField(out, TIFFTAG_SOFTWARE, TIFFGetVersion()); CopyField(TIFFTAG_DOCUMENTNAME, stringv); TIFFSetField(out, TIFFTAG_REFERENCEBLACKWHITE, refBlackWhite); TIFFSetField(out, TIFFTAG_YCBCRSUBSAMPLING, horizSubSampling, vertSubSampling); TIFFSetField(out, TIFFTAG_YCBCRPOSITIONING, YCBCRPOSITION_CENTERED); TIFFSetField(out, TIFFTAG_YCBCRCOEFFICIENTS, ycbcrCoeffs); rowsperstrip = TIFFDefaultStripSize(out, rowsperstrip); TIFFSetField(out, TIFFTAG_ROWSPERSTRIP, rowsperstrip); return (cvtRaster(out, raster, width, height)); }
SDL_Surface* IMG_LoadTIF_RW(SDL_RWops* src) { TIFF* tiff; SDL_Surface* surface = NULL; Uint32 img_width, img_height; Uint32 Rmask, Gmask, Bmask, Amask, mask; Uint32 x, y; Uint32 half; if ( !src ) { /* The error message has been set in SDL_RWFromFile */ return NULL; } /* turn off memory mapped access with the m flag */ tiff = TIFFClientOpen("SDL_image", "rm", (thandle_t)src, tiff_read, tiff_write, tiff_seek, tiff_close, tiff_size, NULL, NULL); if(!tiff) return NULL; /* Retrieve the dimensions of the image from the TIFF tags */ TIFFGetField(tiff, TIFFTAG_IMAGEWIDTH, &img_width); TIFFGetField(tiff, TIFFTAG_IMAGELENGTH, &img_height); Rmask = 0x000000FF; Gmask = 0x0000FF00; Bmask = 0x00FF0000; Amask = 0xFF000000; surface = SDL_AllocSurface(SDL_SWSURFACE, img_width, img_height, 32, Rmask, Gmask, Bmask, Amask); if(!surface) return NULL; if(!TIFFReadRGBAImage(tiff, img_width, img_height, surface->pixels, 0)) return NULL; /* libtiff loads the image upside-down, flip it back */ half = img_height / 2; for(y = 0; y < half; y++) { Uint32 *top = (Uint32 *)surface->pixels + y * surface->pitch/4; Uint32 *bot = (Uint32 *)surface->pixels + (img_height - y - 1) * surface->pitch/4; for(x = 0; x < img_width; x++) { Uint32 tmp = top[x]; top[x] = bot[x]; bot[x] = tmp; } } TIFFClose(tiff); return surface; }
void TiffImage::readImage() { TIFF *tif = TIFFOpen(this->getimageFile().c_str(), "r"); if (tif) { size_t npixels; uint32* raster; TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &imgWidth); TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &imgHeight); TIFFGetField(tif, TIFFTAG_ORIENTATION, &imgOrientation); npixels = imgWidth * imgHeight; //no of pixels in image raster = (uint32*) _TIFFmalloc(npixels * sizeof (uint32)); if (raster != NULL) { if (TIFFReadRGBAImage(tif, imgWidth, imgHeight, raster, 0)) { //...process raster data... //write data in vector member so we can do with it what we want uint32 *rasterPrint = raster; for(size_t n=0;n<npixels;n++) { imgBuffer.push_back(raster[n]); cout << "New Pixel R: "; cout << TIFFGetR(*rasterPrint) << " G: "; cout << TIFFGetG(*rasterPrint) << " B: "; cout << TIFFGetB(*rasterPrint) << " A: "; cout << TIFFGetA(*rasterPrint) << " uint32: "; cout << *rasterPrint << endl; *rasterPrint++; } } _TIFFfree(raster); //TIFFRedRGBAImage is starting in the lower left corner, so we //got to swap our vector. this means we hve to swap first row with last //and so on. uint32 upBufPos, downBufPos; for (uint32 i = 0 ; i < this->imgHeight / 2; i++) { for (uint32 j = 0 ; j < this->imgWidth; j++) { upBufPos = i * this->imgWidth + j; if (i*j == 0) { upBufPos = i+j; } downBufPos = ((this->imgHeight - i - 1) * this->imgWidth) + j; swap(this->imgBuffer[upBufPos], this->imgBuffer[downBufPos]); } } } TIFFClose(tif); } }
PSD GdDecodeTIFF(char *path) { TIFF *tif; int w, h; PSD pmd; MWBLITPARMS parms; static TIFFErrorHandler prev_handler = NULL; if (!prev_handler) prev_handler = TIFFSetErrorHandler(NULL); tif = TIFFOpen(path, "r"); if (!tif) return NULL; TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &w); TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &h); parms.data = NULL; pmd = GdCreatePixmap(&scrdev, w, h, MWIF_RGBA8888, NULL, 0); if (!pmd) goto err; /* Allocate extra image buffer*/ if ((parms.data = malloc(h * pmd->pitch)) == NULL) goto err; TIFFReadRGBAImage(tif, w, h, (uint32 *)parms.data, 0); /* use conversion blit to flip upside down image*/ parms.dstx = parms.dsty = parms.srcx = parms.srcy = 0; parms.width = w; parms.height = h; parms.src_pitch = parms.dst_pitch = pmd->pitch; parms.data_out = pmd->addr; convblit_flipy_8888(&parms); free(parms.data); TIFFClose(tif); return pmd; err: EPRINTF("GdDecodeTIFF: image loading error\n"); if (tif) TIFFClose(tif); if(parms.data) free(parms.data); if (pmd) GdFreePixmap(pmd); return NULL; /* image error*/ }
/* Function to load a single TIFF file as an Image. */ Image loadTIFF(const std::string filename) { TIFF* tif = TIFFOpen(filename.c_str(), "r"); if (!tif) throw std::runtime_error("Failed to open image file"); Image img; TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &(img.width)); TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &(img.height)); img.pixels.resize(img.width * img.height); if (!TIFFReadRGBAImage(tif, img.width, img.height, reinterpret_cast<uint32*>(&img.pixels[0]), 0)) throw std::runtime_error("Failed to read image data"); TIFFClose(tif); return img; }
// Read RGBA TIFFs. // // Return only R-component. // // No intensity remapping. // static void Raster8FromTifRGBA( TIFF *tif, int w, int h, uint8* raster ) { int npixels = w * h; uint32 *raw = (uint32*)malloc( npixels * sizeof(uint32) ); TIFFReadRGBAImage( tif, w, h, raw, 0 ); for( int i = 0; i < npixels; ++i ) raster[i] = raw[i] & 0xFF; free( raw ); }
void vixo_colorPara::init(string fileName,vec3 baseColor,float noiseAmp,int noiseFreq,vector<hairDetail>& hairUVs,int length) { if(fileName!=""||(baseColor.x!=0&&baseColor.y!=0&&baseColor.z!=0)) { hasEffect=true; } else hasEffect=false; hairValue.resize(length*3); if (fileName!="") { TIFF* tif = TIFFOpen(fileName.c_str(), "r"); vector<uint32> pixels; uint32 width,height; if (tif) { size_t npixels; TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width); TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height); npixels = width * height; pixels.resize(npixels); TIFFReadRGBAImage(tif, width, height, &pixels[0], 0); //abgr TIFFClose(tif); } for(int i=0;i<length;i++) { vec3 noiseValue=noise::atPointUVColor(hairUVs[i].u*noiseFreq,hairUVs[i].v*noiseFreq); noiseValue.x=(noiseValue.x*2-1)*noiseAmp; noiseValue.y=(noiseValue.y*2-1)*noiseAmp; noiseValue.z=(noiseValue.z*2-1)*noiseAmp; int line=hairUVs[i].u*width; int col=hairUVs[i].v*height; vec3 res; res.x=(pixels[(col*width+line)]&0xff)/255.0; res.y=((pixels[(col*width+line)]&0xff00)>>8)/255.0; res.z=((pixels[(col*width+line)]&0xff0000)>>16)/255.0; res.x=min(max(res.x+noiseValue.x,0.0f),1.0f); res.y=min(max(res.y+noiseValue.y,0.0f),1.0f); res.z=min(max(res.z+noiseValue.z,0.0f),1.0f); hairValue[3*i]=res.x; hairValue[3*i+1]=res.y; hairValue[3*i+2]=res.z; } }
tdata_t tif_ReadRGBData(TIFF* tif) { int* buffer = (int*)tif_Malloc(tif); char* raster = (char*)tif_Malloc(tif); printf("sizeof(raster) = %ld\n", malloc_usable_size(raster)); printf("sizeof(buffer) = %ld\n", malloc_usable_size(buffer)); int rgba; tsize_t result; uint16 c = tif_nChannels(tif); uint32 w = tif_Width(tif); uint32 h = tif_Height(tif); uint16 ic; uint32 iw, ih; if (tif == NULL) return NULL; if (buffer != NULL) { printf("Reading raster rgba: w = %d, h = %d, c = %d, tif = %p, buffer = %p, raster = %p\n", w, h, c, tif, buffer, raster); result = TIFFReadRGBAImage(tif, w, h, (uint32*)buffer, 0); printf("Result = %ld\n", result); if (result == 0) { printf("Read error on input rgba image.\n"); } printf("Read ok: result = %ld\n", result); } if (raster != NULL) { for(ih = 0; ih < h; ih++){ for(iw = 0; iw < w; iw++){ rgba = buffer[(h-ih-1)*w+iw]; ic = 0; raster[macro_RasterPos2dRgb] = TIFFGetR(rgba); ic = 1; if (c >= 2) raster[macro_RasterPos2dRgb] = TIFFGetG(rgba); ic = 2; if (c >= 3) raster[macro_RasterPos2dRgb] = TIFFGetB(rgba); ic = 3; if (c >= 4) raster[macro_RasterPos2dRgb] = TIFFGetA(rgba); } } } return (tdata_t)raster; }
FrameBuffer * TMesh::openTIFF(string filename){ TIFF *FILE; if((FILE = TIFFOpen(filename.c_str(), "r")) == 0){ return NULL; } //delete(fb); FrameBuffer * fb; int u0 = 50; int v0 = 50; int w = 0; int h = 0; TIFFGetField(FILE, TIFFTAG_IMAGEWIDTH, &w); TIFFGetField(FILE, TIFFTAG_IMAGELENGTH, &h); unsigned int npix = w*h; unsigned int *raster =(unsigned int *) _TIFFmalloc(npix *sizeof(unsigned int)); fb = new FrameBuffer(u0,v0,w,h); //fb->label(filename.c_str()); //fb->show(); int retval = TIFFReadRGBAImage(FILE, w, h, raster); int i = 0; for(int u = 0; u < w; u++){ for(int v = 0; v < h; v++){ fb->Set(u,v,raster[w*(h-1-v) + u]); i++; } } TIFFClose(FILE); _TIFFfree(raster); //Render(); return fb; }
void RawImage::loadTIFF(const char* filename) throw(ImageException) { TIFF* tiff = TIFFOpen(filename, "rb"); if (!tiff) throw ImageException("Unable to open TIFF file."); _type = GL_RGBA; _bytesPerPixel = 4; TIFFGetField(tiff, TIFFTAG_IMAGEWIDTH, &_width); TIFFGetField(tiff, TIFFTAG_IMAGELENGTH, &_height); size_t numPixels = _width * _height; _pixels = new unsigned char[_bytesPerPixel * numPixels]; bool readOK = TIFFReadRGBAImage(tiff, _width, _height, (uint32*)_pixels, 0); TIFFClose(tiff); if (!readOK) throw ImageException("Error reading TIFF data."); }
GImage * GImageReadTiff (char *filename) { TIFF *tif; uint32_t w, h, i, j; uint32_t *ipt, *fpt; size_t npixels; uint32 *raster; GImage *ret = NULL; struct _GImage *base; tif = TIFFOpen (filename, "r"); if (tif == NULL) return (ret); TIFFGetField (tif, TIFFTAG_IMAGEWIDTH, &w); TIFFGetField (tif, TIFFTAG_IMAGELENGTH, &h); npixels = w * h; raster = (uint32_t *) xmalloc (szmax (1, npixels * sizeof (uint32_t))); if (raster != NULL) { if (TIFFReadRGBAImage (tif, w, h, raster, 0)) { ret = GImageCreate (it_true, w, h); if (ret != NULL) { base = ret->u.image; for (i = 0; i < h; ++i) { ipt = (uint32_t *) (base->data + i * base->bytes_per_line); fpt = raster + (h - 1 - i) * w; for (j = 0; j < w; ++j) *ipt++ = COLOR_CREATE (TIFFGetR (fpt[j]), TIFFGetG (fpt[j]), TIFFGetB (fpt[j])); } } } free (raster); } TIFFClose (tif); return (ret); }
/** * Construct the importer. * * @param inputName The name of the input image */ TiffImporter::TiffImporter(FileName inputName) : ImageImporter(inputName) { // Open the TIFF image m_image = NULL; if ((m_image = TIFFOpen(inputName.expanded().toAscii().data(), "r")) == NULL) { throw IException(IException::Programmer, "Could not open incoming image", _FILEINFO_); } // Get its constant dimensions. Note, height seems to get reset to 0 if // called before setting width. uint32 height; TIFFGetField(m_image, TIFFTAG_IMAGELENGTH, &height); setLines(height); uint32 width; TIFFGetField(m_image, TIFFTAG_IMAGEWIDTH, &width); setSamples(width); TIFFGetField(m_image, TIFFTAG_SAMPLESPERPIXEL, &m_samplesPerPixel); // Setup the width and height of the image unsigned long imagesize = lines() * samples(); m_raster = NULL; if ((m_raster = (uint32 *) malloc(sizeof(uint32) * imagesize)) == NULL) { throw IException(IException::Programmer, "Could not allocate enough memory", _FILEINFO_); } // Read the image into the memory buffer if (TIFFReadRGBAImage(m_image, samples(), lines(), m_raster, 0) == 0) { throw IException(IException::Programmer, "Could not read image", _FILEINFO_); } // Deal with photometric interpretations if (TIFFGetField(m_image, TIFFTAG_PHOTOMETRIC, &m_photo) == 0) { throw IException(IException::Programmer, "Image has an undefined photometric interpretation", _FILEINFO_); } setDefaultBands(); }
static int TifReadImage(Tcl_Interp *interp, TIFF *tifPtr, Blt_Chain chain) { int w, h, nPixels; uint32 *srcBits, *sp; Picture *destPtr; Blt_Pixel *destRowPtr; int y; TIFFGetField(tifPtr, TIFFTAG_IMAGEWIDTH, &w); TIFFGetField(tifPtr, TIFFTAG_IMAGELENGTH, &h); nPixels = w * h; srcBits = _TIFFmalloc(sizeof(uint32) * nPixels); if (srcBits == NULL) { Tcl_AppendResult(interp, "can't allocate ", Blt_Itoa(nPixels), " buffer for TIF image", (char *)NULL); return TCL_ERROR; } if (!TIFFReadRGBAImage(tifPtr, w, h, srcBits, /*stopOnError*/0)) { Tcl_AppendResult(interp, "can't read image in directory", (char *)NULL); _TIFFfree(srcBits); return TCL_ERROR; } destPtr = Blt_CreatePicture(w, h); destRowPtr = destPtr->bits + (destPtr->pixelsPerRow * (h - 1)); sp = srcBits; for (y = h - 1; y >= 0; y--) { Blt_Pixel *dp, *dend; for (dp = destRowPtr, dend = dp + w; dp < dend; dp++) { dp->Red = TIFFGetR(*sp); dp->Green = TIFFGetG(*sp); dp->Blue = TIFFGetB(*sp); dp->Alpha = TIFFGetA(*sp); sp++; } destRowPtr -= destPtr->pixelsPerRow; } Blt_Chain_Append(chain, destPtr); return TCL_OK; }
Pic *tiff_read(char *file, Pic *opic) { TIFF *tif; unsigned int npixels; uint32 *raster; int result; uint32 w, h; Pic *pic; tif = TIFFOpen(file, "r"); if( !tif ) return NULL; TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &w); TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &h); npixels = w*h; raster = (uint32 *)_TIFFmalloc(npixels * sizeof(uint32)); if( !raster ) return NULL; result = TIFFReadRGBAImage(tif, w, h, raster, TRUE); if( opic && npixels == (opic->nx * opic->ny)) pic = opic; else pic = pic_alloc(w, h, 3, opic); unpack_tiff_raster(pic, raster); _TIFFfree(raster); TIFFClose(tif); return pic; }
Pic *tiff_read(char *file, Pic *opic) { TIFF *tif; unsigned int npixels; short samples; uint32 *raster; int result; uint32 w, h; Pic *pic; tif = TIFFOpen(file, "r"); if( !tif ) return NULL; TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &w); TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &h); TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &samples); npixels = w*h; raster = (uint32 *)_TIFFmalloc(npixels * sizeof(uint32)); if( !raster ) return NULL; printf("reading TIFF file %s: %dx%d (%d-bit) pixels\n", file, w, h, 8*samples); result = TIFFReadRGBAImage(tif, w, h, raster, TRUE); pic = pic_alloc(w, h, samples, opic); unpack_tiff_raster(pic, raster); _TIFFfree(raster); TIFFClose(tif); return pic; }
bool ZLWin32ImageManager::tiffConvert(const std::string &stringData, ZLWin32ImageData &data, bool &result) const { result = false; TIFFReader reader(stringData); TIFF *tiff = TIFFClientOpen("ZLWin32ImageManager", "rM", &reader, TIFFReader::read, TIFFReader::write, TIFFReader::seek, TIFFReader::close, TIFFReader::size, TIFFReader::map, TIFFReader::unmap); if (tiff == 0) { return false; } int width, height; if (!TIFFGetField(tiff, TIFFTAG_IMAGEWIDTH, &width) || !TIFFGetField(tiff, TIFFTAG_IMAGELENGTH, &height)) { TIFFClose(tiff); return false; } data.init(width, height, true, 0); result = TIFFReadRGBAImage(tiff, width, height, (uint32*)data.myArray, 1) != 0; data.bgr2rgb(); TIFFClose(tiff); return true; }
static void* tiff_init(FILE *fp, char *filename, unsigned int page, struct ida_image_info *i, int thumbnail) { struct tiff_state *h; fclose(fp); h = malloc(sizeof(*h)); memset(h,0,sizeof(*h)); TIFFSetWarningHandler(NULL); h->tif = TIFFOpen(filename,"r"); if (NULL == h->tif) goto oops; /* Determine number of directories */ h->ndirs = 1; while (TIFFReadDirectory(h->tif)) h->ndirs++; i->npages = h->ndirs; /* Select requested directory (page) */ if (!TIFFSetDirectory(h->tif, (tdir_t)page)) goto oops; TIFFGetField(h->tif, TIFFTAG_IMAGEWIDTH, &h->width); TIFFGetField(h->tif, TIFFTAG_IMAGELENGTH, &h->height); TIFFGetField(h->tif, TIFFTAG_PLANARCONFIG, &h->config); TIFFGetField(h->tif, TIFFTAG_SAMPLESPERPIXEL, &h->nsamples); TIFFGetField(h->tif, TIFFTAG_BITSPERSAMPLE, &h->depth); TIFFGetField(h->tif, TIFFTAG_FILLORDER, &h->fillorder); TIFFGetField(h->tif, TIFFTAG_PHOTOMETRIC, &h->photometric); h->row = malloc(TIFFScanlineSize(h->tif)); if (debug) fprintf(stderr,"tiff: %" PRId32 "x%" PRId32 ", planar=%d, " "nsamples=%d, depth=%d fo=%d pm=%d scanline=%" PRId32 "\n", h->width,h->height,h->config,h->nsamples,h->depth, h->fillorder,h->photometric, (uint32_t)TIFFScanlineSize(h->tif)); if (PHOTOMETRIC_PALETTE == h->photometric || PHOTOMETRIC_YCBCR == h->photometric || PHOTOMETRIC_SEPARATED == h->photometric || TIFFIsTiled(h->tif) || (1 != h->depth && 8 != h->depth)) { /* for the more difficuilt cases we let libtiff * do all the hard work. Drawback is that we lose * progressive loading and decode everything here */ if (debug) fprintf(stderr,"tiff: reading whole image [TIFFReadRGBAImage]\n"); h->image=malloc(4*h->width*h->height); TIFFReadRGBAImage(h->tif, h->width, h->height, h->image, 0); } else { if (debug) fprintf(stderr,"tiff: reading scanline by scanline\n"); h->row = malloc(TIFFScanlineSize(h->tif)); } i->width = h->width; i->height = h->height; if (TIFFGetField(h->tif, TIFFTAG_RESOLUTIONUNIT, &h->resunit) && TIFFGetField(h->tif, TIFFTAG_XRESOLUTION, &h->xres) && TIFFGetField(h->tif, TIFFTAG_YRESOLUTION, &h->yres)) { switch (h->resunit) { case RESUNIT_NONE: break; case RESUNIT_INCH: i->dpi = h->xres; break; case RESUNIT_CENTIMETER: i->dpi = res_cm_to_inch(h->xres); break; } } return h; oops: if (h->tif) TIFFClose(h->tif); free(h); return NULL; }
Image *Read (IStream *file, const Image::ReadOptions& options) { int nrow; int result = 0; long LineSize; TIFF *tif; Image *image ; uint16 BitsPerSample; uint16 BytesPerSample = 1; uint16 PhotometricInterpretation; uint16 SamplePerPixel; uint16 Orientation; uint32 RowsPerStrip; unsigned int width; unsigned int height; // TODO - TIFF files probably have some gamma info in them by default, but we're currently ignorant about that. // Until that is fixed, use whatever the user has chosen as default. GammaCurvePtr gamma; if (options.gammacorrect && options.defaultGamma) gamma = TranscodingGammaCurve::Get(options.workingGamma, options.defaultGamma); // [CLi] TIFF is specified to use associated (= premultiplied) alpha, so that's the preferred mode to use for the image container unless the user overrides // (e.g. to handle a non-compliant file). bool premul = true; if (options.premultiplyOverride) premul = options.premultiply; // Rather than have libTIFF complain about tags it doesn't understand, // we just suppress all the warnings. TIFFSetWarningHandler(SuppressTIFFWarnings); TIFFSetErrorHandler(SuppressTIFFWarnings); // Open and do initial processing tif = TIFFClientOpen("Dummy File Name", "r", file, Tiff_Read, Tiff_Write, Tiff_Seek, Tiff_Close, Tiff_Size, Tiff_Map, Tiff_Unmap); if (!tif) return (NULL) ; // Get basic information about the image int ExtraSamples, ExtraSampleInfo; TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width); TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height); TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &BitsPerSample); TIFFGetField(tif, TIFFTAG_ROWSPERSTRIP, &RowsPerStrip); TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &PhotometricInterpretation); TIFFGetField(tif, TIFFTAG_ORIENTATION, &Orientation); TIFFGetFieldDefaulted(tif, TIFFTAG_SAMPLESPERPIXEL, &SamplePerPixel); TIFFGetFieldDefaulted(tif, TIFFTAG_EXTRASAMPLES, &ExtraSamples, &ExtraSampleInfo); // don't support more than 16 bits per sample if (BitsPerSample == 16) { BytesPerSample = 2 ; options.warnings.push_back ("Warning: reading 16 bits/sample TIFF file; components crunched to 8"); } LineSize = TIFFScanlineSize(tif); assert (SamplePerPixel == (int) (LineSize / width) / BytesPerSample); // SamplePerPixel = (int)(LineSize / width); #if 0 // For now we are ignoring the orientation of the image... switch (Orientation) { case ORIENTATION_TOPLEFT: break; case ORIENTATION_TOPRIGHT: break; case ORIENTATION_BOTRIGHT: break; case ORIENTATION_BOTLEFT: break; case ORIENTATION_LEFTTOP: break; case ORIENTATION_RIGHTTOP: break; case ORIENTATION_RIGHTBOT: break; case ORIENTATION_LEFTBOT: break; default: break; } #endif //PhotometricInterpretation = 2 image is RGB //PhotometricInterpretation = 3 image have a color palette if (PhotometricInterpretation == PHOTOMETRIC_PALETTE && (TIFFIsTiled(tif) == 0)) { uint16 *red, *green, *blue; //load the palette int cmap_len = (1 << BitsPerSample); TIFFGetField(tif, TIFFTAG_COLORMAP, &red, &green, &blue); vector<Image::RGBMapEntry> colormap ; Image::RGBMapEntry entry; // I may be mistaken, but it appears that alpha/opacity information doesn't // appear in a Paletted Tiff image. Well - if it does, it's not as easy to // get at as RGB. // Read the palette // Is the palette 16 or 8 bits ? if (checkcmap(cmap_len, red, green, blue) == 16) { for (int i=0;i<cmap_len;i++) { entry.red = IntDecode(gamma, red[i], 65535); entry.green = IntDecode(gamma, green[i], 65535); entry.blue = IntDecode(gamma, blue[i], 65535); colormap.push_back (entry); } } else { for (int i=0;i<cmap_len;i++) { entry.red = IntDecode(gamma, red[i], 255); entry.green = IntDecode(gamma, green[i], 255); entry.blue = IntDecode(gamma, blue[i], 255); colormap.push_back (entry); } } Image::ImageDataType imagetype = options.itype; if (imagetype == Image::Undefined) imagetype = Image::Colour_Map; image = Image::Create (width, height, imagetype, colormap) ; image->SetPremultiplied(premul); // specify whether the color map data has premultiplied alpha boost::scoped_array<unsigned char> buf (new unsigned char [TIFFStripSize(tif)]); //read the tiff lines and save them in the image //with RGB mode, we have to change the order of the 3 samples RGB <=> BGR for (int row=0;row<height;row+=RowsPerStrip) { nrow = (row + (int)RowsPerStrip > height ? height - row : RowsPerStrip); TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, row, 0), buf.get(), nrow * LineSize); for (int l = 0, offset = 0; l < nrow ; l++, offset += LineSize) for (int x = 0 ; x < width ; x++) image->SetIndexedValue (x, row+l, buf[offset+x]) ; } } else { // Allocate the row buffers for the image boost::scoped_array<uint32> buf (new uint32 [width * height]) ; Image::ImageDataType imagetype = options.itype; if (imagetype == Image::Undefined) imagetype = ( GammaCurve::IsNeutral(gamma) ? Image::RGBA_Int8 : Image::RGBA_Gamma8 ); image = Image::Create (width, height, imagetype) ; image->SetPremultiplied(premul); // set desired storage mode regarding alpha premultiplication image->TryDeferDecoding(gamma, 255); // try to have gamma adjustment being deferred until image evaluation. TIFFReadRGBAImage(tif, width, height, buf.get(), 0); uint32 abgr, *tbuf = buf.get(); for (int i=height-1;i>=0;i--) { for (int j=0;j<width;j++) { abgr = *tbuf++; unsigned int b = (unsigned char)TIFFGetB(abgr); unsigned int g = (unsigned char)TIFFGetG(abgr); unsigned int r = (unsigned char)TIFFGetR(abgr); unsigned int a = (unsigned char)TIFFGetA(abgr); SetEncodedRGBAValue(image, j, i, gamma, 255, r, g, b, a, premul) ; } } } TIFFClose(tif); return (image) ; }
BOOL CImageTIFF::Read(FILE* stream) { TIFF* m_tif = TIFFOpenEx(stream, "rb"); uint32 height=0; uint32 width=0; uint16 bitspersample=1; uint16 samplesperpixel=1; uint32 rowsperstrip=-1; uint16 photometric=0; uint16 compression=1; uint32 x, y; BOOL isRGB; BYTE *bits; //pointer to source data BYTE *bits2; //pointer to destination data try{ //check if it's a tiff file if (!m_tif) throw "Error encountered while opening TIFF file"; m_info.nNumFrames=0; while(TIFFSetDirectory(m_tif,(uint16)m_info.nNumFrames)) m_info.nNumFrames++; if (!TIFFSetDirectory(m_tif, (uint16)m_info.nFrame)) throw "Error: page not present in TIFF file"; //get image m_info TIFFGetField(m_tif, TIFFTAG_COMPRESSION, &compression); if (compression == COMPRESSION_LZW) throw "LZW compression is no longer supported due to Unisys patent enforcement"; TIFFGetField(m_tif, TIFFTAG_IMAGEWIDTH, &width); TIFFGetField(m_tif, TIFFTAG_IMAGELENGTH, &height); TIFFGetField(m_tif, TIFFTAG_SAMPLESPERPIXEL, &samplesperpixel); TIFFGetField(m_tif, TIFFTAG_BITSPERSAMPLE, &bitspersample); TIFFGetField(m_tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip); TIFFGetField(m_tif, TIFFTAG_PHOTOMETRIC, &photometric); m_header.biWidth = width; m_header.biHeight = height; m_header.biClrUsed=0; m_info.nBkgndIndex =-1; isRGB = (bitspersample >= 8) && (photometric == PHOTOMETRIC_RGB) || (photometric == PHOTOMETRIC_YCBCR) || (photometric == PHOTOMETRIC_SEPARATED) || (photometric == PHOTOMETRIC_LOGLUV); if (isRGB){ m_header.biBitCount=24; m_info.bColorType = COLORTYPE_COLOR; }else{ m_info.bColorType = COLORTYPE_PALETTE; if ((photometric==PHOTOMETRIC_MINISBLACK)||(photometric==PHOTOMETRIC_MINISWHITE)){ if (bitspersample == 1){ m_header.biBitCount=1; //B&W image m_header.biClrUsed =2; } else { m_header.biBitCount=8; //gray scale m_header.biClrUsed =256; } } else if (bitspersample == 4) { m_header.biBitCount=4; // 16 colors m_header.biClrUsed=16; } else { m_header.biBitCount=8; //256 colors m_header.biClrUsed=256; } } Create(m_header.biWidth,m_header.biHeight,m_header.biBitCount); //image creation if (isRGB) { // Read the whole image into one big RGBA buffer using // the traditional TIFFReadRGBAImage() API that we trust. uint32* raster; // retrieve RGBA image uint32 *row; raster = (uint32*)_TIFFmalloc(width * height * sizeof (uint32)); if (raster == NULL) throw "No space for raster buffer"; // Read the image in one chunk into an RGBA array if(!TIFFReadRGBAImage(m_tif, width, height, raster, 1)) { _TIFFfree(raster); throw "Corrupted TIFF file!"; } // read the raster lines and save them in the DIB // with RGB mode, we have to change the order of the 3 samples RGB row = &raster[0]; bits2 = m_info.pImage; for (y = 0; y < height; y++) { bits = bits2; for (x = 0; x < width; x++) { *bits++ = (BYTE)TIFFGetB(row[x]); *bits++ = (BYTE)TIFFGetG(row[x]); *bits++ = (BYTE)TIFFGetR(row[x]); } row += width; bits2 += m_info.dwEffWidth; } _TIFFfree(raster); } else { RGBQUAD *pal; pal=(RGBQUAD*)calloc(256,sizeof(RGBQUAD)); if (pal==NULL) throw "Unable to allocate TIFF palette"; // set up the colormap based on photometric switch(photometric) { case PHOTOMETRIC_MINISBLACK: // bitmap and greyscale image types case PHOTOMETRIC_MINISWHITE: if (bitspersample == 1) { // Monochrome image if (photometric == PHOTOMETRIC_MINISBLACK) { pal[1].rgbRed = pal[1].rgbGreen = pal[1].rgbBlue = 255; } else { pal[0].rgbRed = pal[0].rgbGreen = pal[0].rgbBlue = 255; } } else { // need to build the scale for greyscale images if (photometric == PHOTOMETRIC_MINISBLACK) { for (int i = 0; i < 256; i++) { pal[i].rgbRed = pal[i].rgbGreen = pal[i].rgbBlue = i; } } else { for (int i = 0; i < 256; i++) { pal[i].rgbRed = pal[i].rgbGreen = pal[i].rgbBlue = 255 - i; } } } break; case PHOTOMETRIC_PALETTE: // color map indexed uint16 *red; uint16 *green; uint16 *blue; TIFFGetField(m_tif, TIFFTAG_COLORMAP, &red, &green, &blue); // Is the palette 16 or 8 bits ? BOOL Palette16Bits = FALSE; int n=1<<bitspersample; while (n-- > 0) { if (red[n] >= 256 || green[n] >= 256 || blue[n] >= 256) { Palette16Bits=TRUE; break; } } // load the palette in the DIB for (int i = (1 << bitspersample) - 1; i >= 0; i--) { if (Palette16Bits) { pal[i].rgbRed =(BYTE) CVT(red[i]); pal[i].rgbGreen = (BYTE) CVT(green[i]); pal[i].rgbBlue = (BYTE) CVT(blue[i]); } else { pal[i].rgbRed = (BYTE) red[i]; pal[i].rgbGreen = (BYTE) green[i]; pal[i].rgbBlue = (BYTE) blue[i]; } } break; } SetPalette(pal,m_header.biClrUsed); //palette assign free(pal); // read the tiff lines and save them in the DIB uint32 nrow; uint32 ys; int line = CalculateLine(width, bitspersample * samplesperpixel); // int pitch = CalculatePitch(line); long bitsize= TIFFStripSize(m_tif); bits = (BYTE*)malloc(bitsize); for (ys = 0; ys < height; ys += rowsperstrip) { nrow = (ys + rowsperstrip > height ? height - ys : rowsperstrip); if (TIFFReadEncodedStrip(m_tif, TIFFComputeStrip(m_tif, ys, 0), bits, nrow * line) == -1) { free(bits); throw "Corrupted TIFF file!"; } for (y = 0; y < nrow; y++) { memcpy(m_info.pImage+m_info.dwEffWidth*(height-ys-nrow+y),bits+(nrow-y-1)*line,line); } /*if (m_header.biClrUsed==2){ for (y = 0; y < nrow; y++) { for (x = 0; x < width; x++) { SetPixelIndex(x,y+ys,(bits[y*line+(x>>3)]>>(7-x%8))&0x01); }}}*/ } free(bits); } } catch (char *message) { strncpy(m_info.szLastError,message,255); if (m_tif) TIFFClose(m_tif); return FALSE; } TIFFClose(m_tif); return TRUE; }
ImageIO::errorType ImageIO::loadTIFF(const char * filename) { #ifdef ENABLE_TIFF TIFF * tiff = TIFFOpen(filename, "r"); if (!tiff) return IO_ERROR; // read the dimensions uint32 tiff_width, tiff_height; uint16 tiff_samplesPerPixel; uint16 tiff_bits; TIFFGetField(tiff, TIFFTAG_IMAGEWIDTH, &tiff_width); TIFFGetField(tiff, TIFFTAG_IMAGELENGTH, &tiff_height); TIFFGetField(tiff, TIFFTAG_SAMPLESPERPIXEL, &tiff_samplesPerPixel); TIFFGetField(tiff, TIFFTAG_BITSPERSAMPLE, &tiff_bits); //printf("tiff_width: %d tiff_height: %d tiff_samplesPerPixel: %d tiff_bits: %d\n", tiff_width, tiff_height, tiff_samplesPerPixel, tiff_bits); if ((tiff_samplesPerPixel != IMAGE_IO_RGB) && (tiff_samplesPerPixel != IMAGE_IO_RGB_ALPHA)) { printf("Error in loadTIFF: Sorry, cannot handle %d-channel images.\n", tiff_samplesPerPixel); TIFFClose(tiff); return OTHER_ERROR; } if (tiff_bits != BITS_PER_CHANNEL_8) { printf("Error in loadTIFF: Sorry, cannot handle %d-bit images.\n", tiff_bits); TIFFClose(tiff); return OTHER_ERROR; } width = tiff_width; height = tiff_height; bytesPerPixel = tiff_samplesPerPixel; uint32 * tiff_pixels = (uint32*) _TIFFmalloc(tiff_width * tiff_height * sizeof(uint32)); if (!tiff_pixels) { TIFFClose(tiff); return MEMORY_ERROR; } printf("Loading TIFF image from file %s: resolution: %d x %d, %d-bit.\n", filename, width, height, 8 * bytesPerPixel); int stopOnError = 1; if (!TIFFReadRGBAImage(tiff, tiff_width, tiff_height, tiff_pixels, stopOnError)) { _TIFFfree(tiff_pixels); TIFFClose(tiff); printf("Error in loadTIFF: Unknown error when calling TIFFReadRGBAImage.\n"); return IO_ERROR; } pixels = (unsigned char*) malloc (sizeof(unsigned char) * width * height * bytesPerPixel); // write tiff_pixels into the pixels array int counter = 0; for(unsigned int row=0; row < height; row++) { for(unsigned int column=0; column < width; column++) { // read the uint32 pixel uint32 tiff_pixel = tiff_pixels[row * tiff_width + column]; // write R,G,B,A in place into pixels pixels[counter] = TIFFGetR(tiff_pixel); counter++; if (bytesPerPixel < 3) continue; pixels[counter] = TIFFGetG(tiff_pixel); counter++; pixels[counter] = TIFFGetB(tiff_pixel); counter++; if (bytesPerPixel < 4) continue; // alpha channel pixels[counter] = TIFFGetA(tiff_pixel); counter++; } } _TIFFfree(tiff_pixels); TIFFClose(tiff); return OK; #else return INVALID_FILE_FORMAT; #endif }
main(int argc, char* argv[]) { //START; // the required page number in a multipage tiff, use 0 for first page int dir_num; dir_num = atoi(argv[2]); //time_t start, end; double duration; TIFF* tif = TIFFOpen(argv[1], "r"); //get number of pages (Directories) in a tiff file int dir_count; dir_count = TIFFNumberOfDirectories(tif); if(dir_num < 0 || dir_num > (dir_count-1)){ printf("Error: invalid directory number\n"); exit -1; } else{ if (tif) { uint32 w, h; size_t npixels; uint32* raster; // set the required page (directory) // change to the requested directory and read its contents with TIFFReadDirectory TIFFSetDirectory(tif,dir_num); TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &w); TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &h); npixels = w * h; int r,v; //Foreground and Background pixel values int F = 1, B = 0; size_t c_h, c_w; raster = (uint32*) _TIFFmalloc(npixels * sizeof (uint32)); // image matrix with added boundary pixels int** I = malloc((h+2) * sizeof(int*)); // allocate the rows for ( r = 0; r < (h+2); ++r) { I[r] = malloc((w+2) * sizeof(int)); // allocate the columns //for ( cx = 0; cx < COLS; ++cx) // I[r][cx] = 0; } // an array of pixel runs (hashtable of pixel runs) // each run is a linked list of pixels struct pixel **runs = malloc((h*w/4) * sizeof(struct pixel)); //initialise arrays and linked list for ( v = 0; v < (h*w/4); ++v) { //C[r] = r; // initialise labels init_pixel(runs[v], 99,99); } // arrays to save classes and their mappings //uint32* C = malloc((ROWS*COLS/2) * sizeof(uint32*)); uint32* rl_table = malloc((h*w/4) * sizeof(uint32*)); uint32* n_label = malloc((h*w/4) * sizeof(uint32*)); uint32* t_label = malloc((h*w/4) * sizeof(uint32*)); for ( v = 0; v < (h*w/4); ++v) { //C[r] = r; // initialise classes rl_table[v] = v; n_label[v] = -1; t_label[v] = v; } // load image into matrix of F and B pixels (1's and 0's) if (raster != NULL) { if (TIFFReadRGBAImage(tif, w, h, raster, 0)) { for(c_h=0;c_h<h;c_h++) { for(c_w=0;c_w<w;c_w++) { v = raster[(w*h)-((c_h*w)+(w-c_w))]%256; if (v == 0) I[c_h+1][c_w+1] = F; else I[c_h+1][c_w+1] = B; } } } _TIFFfree(raster); } /* c2 c3 c4 c1 x */ // FIRST SCAN int i,j,k; int NewLabel=5; int c1,c2,c3,c4,uu,vv,ii; for(c_h=1;c_h<(h-1);c_h++) for(c_w=1;c_w<(w-1);c_w++){ // for COLS if (I[c_h][c_w] == F) { c3 = I[c_h-1][c_w] ; if (c3 != B) { I[c_h][c_w] = c3; } else // else1 { c4 = I[c_h-1][c_w+1] ; c1 = I[c_h][c_w-1] ; if (c1 != B) { I[c_h][c_w] = c1; if (c4 != B && c4 != c1) { //printf ("(%d,%d);", c1, c4); //(* resolve c2 c4 *) uu = rl_table[c1]; vv = rl_table[c4]; if(uu<vv){ ii = vv; while(ii != -1){ rl_table[ii] = uu; ii = n_label[ii]; } n_label[t_label[uu]] = vv; t_label[uu] = t_label[vv]; } else{ if(vv<uu){ ii = uu; while(ii != -1){ rl_table[ii] = vv; ii = n_label[ii]; } n_label[t_label[vv]] = uu; t_label[vv] = t_label[uu]; } } } } else // else2 { c2 = I[c_h-1][c_w-1] ; if (c2 != B) { I[c_h][c_w] = c2; if (c4 != B && c4 != c2) { //printf("(%d,%d);\n", c2, c4); //(* resolve c2 c4 *) uu = rl_table[c2]; vv = rl_table[c4]; if(uu<vv){ ii = vv; while(ii != -1){ rl_table[ii] = uu; ii = n_label[ii]; } n_label[t_label[uu]] = vv; t_label[uu] = t_label[vv]; } else{ if(vv<uu){ ii = uu; while(ii != -1){ rl_table[ii] = vv; ii = n_label[ii]; } n_label[t_label[vv]] = uu; t_label[vv] = t_label[uu]; } } } } else if (c4 != B) { I[c_h][c_w] = c4; } else { I[c_h][c_w] = NewLabel; NewLabel=NewLabel+1; } }// else2 }// else1 } } // end for COLS // SECOND SCAN for(c_h=0;c_h<h;c_h++) for(c_w=0;c_w<w;c_w++) // for COLS if (I[c_h][c_w] != B) I[c_h][c_w] = rl_table[I[c_h][c_w]]; //get linked lists of pixels with the same class //i.e. pixels that belong to the same CC for(c_h=0;c_h<h;c_h++){ for(c_w=0;c_w<w;c_w++){ if (I[c_h][c_w] != B) { push(&runs[I[c_h][c_w]], c_w,c_h); } } } //now open a file, find coords of each CC and save them // char *base = get_basename(argv[1]);// = "filename"; char *base = argv[1]; // find location of last '.' in filename to chop extension char *pos = strrchr (base, '.'); int pos1 = pos ? (pos - base ) : -1; if(pos1 != -1){ base[pos1] = 0; // remove file extension //printf("%d, %s\n",pos1, base); } //I'm assuming length of filename doesn't exceed 50 chars //I'll deal with this later char filename[256]; FILE *file; //fname1[strlen(fname1) - 4] = 0; // remove file extension sprintf(filename, "%s-%d.json", base, dir_num); //printf("%s\n", filename); file = fopen(filename,"w+"); fprintf(file,"{\n"); fprintf(file," \"SrcImage\": \"\",\n"); fprintf(file," \"Page\": %d,\n",dir_num); fprintf(file," \"PageWidth\": %d,\n", w); fprintf(file," \"PageHeight\": %d,\n",h); fprintf(file," \"ClipX\": %d,\n",0); fprintf(file," \"ClipY\": %d,\n",0); fprintf(file," \"ClipWidth\": %d,\n", w); fprintf(file," \"ClipHeight\": %d,\n",h); fprintf(file," \"ClipImage\": \"\",\n"); fprintf(file," \"glyphs\": [\n"); //count++; //file = fopen("file.txt","w+"); int len; for ( v = 0; v < (h*w/4); ++v) { len = length(runs[v]); if (len > 0 ){ //printf("run ID: %d, run length %d\n", r, len ); struct bbox* b = find_bbox (runs[v]); //printf("bbox: (%d,%d),(%d,%d)\n", b->x1, b->y1, b->x2, b->y2 ); fprintf(file," { \"x\" : %d, \"y\" : %d, \"w\" : %d, \"h\" : %d }",(b->x1-1),(b->y1-1), (b->x2 - b->x1 + 1), (b->y2 - b->y1 + 1)); fprintf(file, ",\n"); free(runs[v]);// = NULL; free(b); } } // trick by Volker to remove comma after last glyph fseek(file, -( 2*(int)sizeof(char) ), SEEK_CUR); fprintf(file,"\n ]\n"); fprintf(file,"}\n"); // close file fclose(file); //printf("Generated: %s\n",filename); //manually free space allocated to various arrays and matrices for (v = 0; v < h; ++v) { free(I[v]); // this frees the columns } free(I); // this frees the rows free(runs); //free(C); free(rl_table); free(n_label); free(t_label); TIFFClose(tif); }//end if tif } //end else //STOP; //PRINTTIME; }
static int tiffcvt(TIFF* in, TIFF* out) { uint32 width, height; /* image width & height */ uint32* raster; /* retrieve RGBA image */ uint16 shortv; float floatv; char *stringv; uint32 longv; size_t pixel_count; TIFFGetField(in, TIFFTAG_IMAGEWIDTH, &width); TIFFGetField(in, TIFFTAG_IMAGELENGTH, &height); pixel_count = width * height; /* XXX: Check the integer overflow. */ if (!width || !height || pixel_count / width != height) { TIFFError(TIFFFileName(in), "Malformed input file; " "can't allocate buffer for raster of %lux%lu size", (unsigned long)width, (unsigned long)height); return 0; } raster = (uint32*)_TIFFCheckMalloc(in, pixel_count, sizeof(uint32), "raster buffer"); if (raster == 0) { TIFFError(TIFFFileName(in), "Requested buffer size is %lu elements %lu each", (unsigned long)pixel_count, (unsigned long)sizeof(uint32)); return (0); } if (!TIFFReadRGBAImage(in, width, height, raster, 0)) { _TIFFfree(raster); return (0); } CopyField(TIFFTAG_SUBFILETYPE, longv); TIFFSetField(out, TIFFTAG_IMAGEWIDTH, width); TIFFSetField(out, TIFFTAG_IMAGELENGTH, height); TIFFSetField(out, TIFFTAG_BITSPERSAMPLE, 8); TIFFSetField(out, TIFFTAG_COMPRESSION, compression); TIFFSetField(out, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_YCBCR); if (compression == COMPRESSION_JPEG) TIFFSetField(out, TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RAW); CopyField(TIFFTAG_FILLORDER, shortv); TIFFSetField(out, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT); TIFFSetField(out, TIFFTAG_SAMPLESPERPIXEL, 3); CopyField(TIFFTAG_XRESOLUTION, floatv); CopyField(TIFFTAG_YRESOLUTION, floatv); CopyField(TIFFTAG_RESOLUTIONUNIT, shortv); TIFFSetField(out, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); { char buf[2048]; char *cp = strrchr(TIFFFileName(in), '/'); sprintf(buf, "YCbCr conversion of %s", cp ? cp+1 : TIFFFileName(in)); TIFFSetField(out, TIFFTAG_IMAGEDESCRIPTION, buf); } TIFFSetField(out, TIFFTAG_SOFTWARE, TIFFGetVersion()); CopyField(TIFFTAG_DOCUMENTNAME, stringv); TIFFSetField(out, TIFFTAG_REFERENCEBLACKWHITE, refBlackWhite); TIFFSetField(out, TIFFTAG_YCBCRSUBSAMPLING, horizSubSampling, vertSubSampling); TIFFSetField(out, TIFFTAG_YCBCRPOSITIONING, YCBCRPOSITION_CENTERED); TIFFSetField(out, TIFFTAG_YCBCRCOEFFICIENTS, ycbcrCoeffs); rowsperstrip = TIFFDefaultStripSize(out, rowsperstrip); TIFFSetField(out, TIFFTAG_ROWSPERSTRIP, rowsperstrip); return (cvtRaster(out, raster, width, height)); }
bool CxImageTIF::Decode(CxFile * hFile) { //Comment this line if you need more information on errors // TIFFSetErrorHandler(NULL); //<Patrick Hoffmann> //Open file and fill the TIFF structure // m_tif = TIFFOpen(imageFileName,"rb"); TIFF* m_tif = _TIFFOpenEx(hFile, "rb"); uint32 height=0; uint32 width=0; uint16 bitspersample=1; uint16 samplesperpixel=1; uint32 rowsperstrip=(uint32_t)-1; uint16 photometric=0; uint16 compression=1; uint16 orientation=ORIENTATION_TOPLEFT; //<vho> uint16 res_unit; //<Trifon> uint32 x, y; float resolution, offset; bool isRGB; uint8_t *bits; //pointer to source data uint8_t *bits2; //pointer to destination data cx_try { //check if it's a tiff file if (!m_tif) cx_throw("Error encountered while opening TIFF file"); // <Robert Abram> - 12/2002 : get NumFrames directly, instead of looping // info.nNumFrames=0; // while(TIFFSetDirectory(m_tif,(uint16)info.nNumFrames)) info.nNumFrames++; info.nNumFrames = TIFFNumberOfDirectories(m_tif); if (!TIFFSetDirectory(m_tif, (uint16)info.nFrame)) cx_throw("Error: page not present in TIFF file"); //get image info TIFFGetField(m_tif, TIFFTAG_IMAGEWIDTH, &width); TIFFGetField(m_tif, TIFFTAG_IMAGELENGTH, &height); TIFFGetField(m_tif, TIFFTAG_SAMPLESPERPIXEL, &samplesperpixel); TIFFGetField(m_tif, TIFFTAG_BITSPERSAMPLE, &bitspersample); TIFFGetField(m_tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip); TIFFGetField(m_tif, TIFFTAG_PHOTOMETRIC, &photometric); TIFFGetField(m_tif, TIFFTAG_ORIENTATION, &orientation); if (info.nEscape == -1) { // Return output dimensions only head.biWidth = width; head.biHeight = height; info.dwType = CXIMAGE_FORMAT_TIF; cx_throw("output dimensions returned"); } TIFFGetFieldDefaulted(m_tif, TIFFTAG_RESOLUTIONUNIT, &res_unit); if (TIFFGetField(m_tif, TIFFTAG_XRESOLUTION, &resolution)) { if (res_unit == RESUNIT_CENTIMETER) resolution = (float)(resolution*2.54f + 0.5f); SetXDPI((int32_t)resolution); } if (TIFFGetField(m_tif, TIFFTAG_YRESOLUTION, &resolution)) { if (res_unit == RESUNIT_CENTIMETER) resolution = (float)(resolution*2.54f + 0.5f); SetYDPI((int32_t)resolution); } if (TIFFGetField(m_tif, TIFFTAG_XPOSITION, &offset)) info.xOffset = (int32_t)offset; if (TIFFGetField(m_tif, TIFFTAG_YPOSITION, &offset)) info.yOffset = (int32_t)offset; head.biClrUsed=0; info.nBkgndIndex =-1; if (rowsperstrip>height){ rowsperstrip=height; TIFFSetField(m_tif, TIFFTAG_ROWSPERSTRIP, rowsperstrip); } isRGB = /*(bitspersample >= 8) && (VK: it is possible so for RGB to have < 8 bpp!)*/ (photometric == PHOTOMETRIC_RGB) || (photometric == PHOTOMETRIC_YCBCR) || (photometric == PHOTOMETRIC_SEPARATED) || (photometric == PHOTOMETRIC_LOGL) || (photometric == PHOTOMETRIC_LOGLUV); if (isRGB){ head.biBitCount=24; }else{ if ((photometric==PHOTOMETRIC_MINISBLACK)||(photometric==PHOTOMETRIC_MINISWHITE)||(photometric==PHOTOMETRIC_PALETTE)){ if (bitspersample == 1){ head.biBitCount=1; //B&W image head.biClrUsed =2; } else if (bitspersample == 4) { head.biBitCount=4; //16 colors gray scale head.biClrUsed =16; } else { head.biBitCount=8; //gray scale head.biClrUsed =256; } } else if (bitspersample == 4) { head.biBitCount=4; // 16 colors head.biClrUsed=16; } else { head.biBitCount=8; //256 colors head.biClrUsed=256; } if ((bitspersample > 8) && (photometric==PHOTOMETRIC_PALETTE)) // + VK + (BIG palette! => convert to RGB) { head.biBitCount=24; head.biClrUsed =0; } } if (info.nEscape) cx_throw("Cancelled"); // <vho> - cancel decoding Create(width,height,head.biBitCount,CXIMAGE_FORMAT_TIF); //image creation if (!pDib) cx_throw("CxImageTIF can't create image"); #if CXIMAGE_SUPPORT_ALPHA if (samplesperpixel==4) AlphaCreate(); //add alpha support for 32bpp tiffs if (samplesperpixel==2 && bitspersample==8) AlphaCreate(); //add alpha support for 8bpp + alpha #endif //CXIMAGE_SUPPORT_ALPHA TIFFGetField(m_tif, TIFFTAG_COMPRESSION, &compression); SetCodecOption(compression); // <DPR> save original compression type if (isRGB) { // Read the whole image into one big RGBA buffer using // the traditional TIFFReadRGBAImage() API that we trust. uint32* raster; // retrieve RGBA image uint32 *row; raster = (uint32*)_TIFFmalloc(width * height * sizeof (uint32)); if (raster == NULL) cx_throw("No space for raster buffer"); // Read the image in one chunk into an RGBA array if(!TIFFReadRGBAImage(m_tif, width, height, raster, 1)) { _TIFFfree(raster); cx_throw("Corrupted TIFF file!"); } // read the raster lines and save them in the DIB // with RGB mode, we have to change the order of the 3 samples RGB row = &raster[0]; bits2 = info.pImage; for (y = 0; y < height; y++) { if (info.nEscape){ // <vho> - cancel decoding _TIFFfree(raster); cx_throw("Cancelled"); } bits = bits2; for (x = 0; x < width; x++) { *bits++ = (uint8_t)TIFFGetB(row[x]); *bits++ = (uint8_t)TIFFGetG(row[x]); *bits++ = (uint8_t)TIFFGetR(row[x]); #if CXIMAGE_SUPPORT_ALPHA if (samplesperpixel==4) AlphaSet(x,y,(uint8_t)TIFFGetA(row[x])); #endif //CXIMAGE_SUPPORT_ALPHA } row += width; bits2 += info.dwEffWidth; } _TIFFfree(raster); } else { int32_t BIG_palette = (bitspersample > 8) && // + VK (photometric==PHOTOMETRIC_PALETTE); if (BIG_palette && (bitspersample > 24)) // + VK cx_throw("Too big palette to handle"); // + VK RGBQuad *pal; pal=(RGBQuad*)calloc(BIG_palette ? 1<<bitspersample : 256,sizeof(RGBQuad)); // ! VK: it coasts nothing but more correct to use 256 as temp palette storage // ! VK: but for case of BIG palette it just copied if (pal==NULL) cx_throw("Unable to allocate TIFF palette"); int32_t bpp = bitspersample <= 8 ? bitspersample : 8; // + VK (to use instead of bitspersample for case of > 8) // set up the colormap based on photometric switch(photometric) { case PHOTOMETRIC_MINISBLACK: // bitmap and greyscale image types case PHOTOMETRIC_MINISWHITE: if (bitspersample == 1) { // Monochrome image if (photometric == PHOTOMETRIC_MINISBLACK) { pal[1].rgbRed = pal[1].rgbGreen = pal[1].rgbBlue = 255; } else { pal[0].rgbRed = pal[0].rgbGreen = pal[0].rgbBlue = 255; } } else { // need to build the scale for greyscale images if (photometric == PHOTOMETRIC_MINISBLACK) { for (int32_t i=0; i<(1<<bpp); i++){ pal[i].rgbRed = pal[i].rgbGreen = pal[i].rgbBlue = (uint8_t)(i*(255/((1<<bpp)-1))); } } else { for (int32_t i=0; i<(1<<bpp); i++){ pal[i].rgbRed = pal[i].rgbGreen = pal[i].rgbBlue = (uint8_t)(255-i*(255/((1<<bpp)-1))); } } } break; case PHOTOMETRIC_PALETTE: // color map indexed uint16 *red; uint16 *green; uint16 *blue; TIFFGetField(m_tif, TIFFTAG_COLORMAP, &red, &green, &blue); // Is the palette 16 or 8 bits ? bool Palette16Bits = /*false*/ BIG_palette; if (!BIG_palette) { int32_t n= 1<<bpp; while (n-- > 0) { if (red[n] >= 256 || green[n] >= 256 || blue[n] >= 256) { Palette16Bits=true; break; } } } // load the palette in the DIB for (int32_t i = (1 << ( BIG_palette ? bitspersample : bpp )) - 1; i >= 0; i--) { if (Palette16Bits) { pal[i].rgbRed =(uint8_t) CVT(red[i]); pal[i].rgbGreen = (uint8_t) CVT(green[i]); pal[i].rgbBlue = (uint8_t) CVT(blue[i]); } else { pal[i].rgbRed = (uint8_t) red[i]; pal[i].rgbGreen = (uint8_t) green[i]; pal[i].rgbBlue = (uint8_t) blue[i]; } } break; } if (!BIG_palette) { // + VK (BIG palette is stored until image is ready) SetPalette(pal,/*head.biClrUsed*/ 1<<bpp); //palette assign // * VK free(pal); pal = NULL; } // read the tiff lines and save them in the DIB uint32 nrow; uint32 ys; int32_t line = CalculateLine(width, bitspersample * samplesperpixel); int32_t bitsize = TIFFStripSize(m_tif); //verify bitsize: could be wrong if StripByteCounts is missing. if (bitsize>(int32_t)(head.biSizeImage*samplesperpixel)) bitsize = head.biSizeImage*samplesperpixel; if (bitsize<(int32_t)(info.dwEffWidth*rowsperstrip)) bitsize = info.dwEffWidth*rowsperstrip; if ((bitspersample > 8) && (bitspersample != 16)) // + VK (for bitspersample == 9..15,17..32..64 bitsize *= (bitspersample + 7)/8; int32_t tiled_image = TIFFIsTiled(m_tif); uint32 tw=0, tl=0; uint8_t* tilebuf=NULL; if (tiled_image){ TIFFGetField(m_tif, TIFFTAG_TILEWIDTH, &tw); TIFFGetField(m_tif, TIFFTAG_TILELENGTH, &tl); rowsperstrip = tl; bitsize = TIFFTileSize(m_tif) * (int32_t)(1+width/tw); tilebuf = (uint8_t*)malloc(TIFFTileSize(m_tif)); } bits = (uint8_t*)malloc(bitspersample==16? bitsize*2 : bitsize); // * VK uint8_t * bits16 = NULL; // + VK int32_t line16 = 0; // + VK if (!tiled_image && bitspersample==16) { // + VK + line16 = line; line = CalculateLine(width, 8 * samplesperpixel); bits16 = bits; bits = (uint8_t*)malloc(bitsize); } if (bits==NULL){ if (bits16) free(bits16); // + VK if (pal) free(pal); // + VK if (tilebuf)free(tilebuf); // + VK cx_throw("CxImageTIF can't allocate memory"); } #ifdef FIX_16BPP_DARKIMG // + VK: for each line, store shift count bits used to fix it uint8_t* row_shifts = NULL; if (bits16) row_shifts = (uint8_t*)malloc(height); #endif for (ys = 0; ys < height; ys += rowsperstrip) { if (info.nEscape){ // <vho> - cancel decoding free(bits); cx_throw("Cancelled"); } nrow = (ys + rowsperstrip > height ? height - ys : rowsperstrip); if (tiled_image){ uint32 imagew = TIFFScanlineSize(m_tif); uint32 tilew = TIFFTileRowSize(m_tif); int32_t iskew = imagew - tilew; uint8* bufp = (uint8*) bits; uint32 colb = 0; for (uint32 col = 0; col < width; col += tw) { if (TIFFReadTile(m_tif, tilebuf, col, ys, 0, 0) < 0){ free(tilebuf); free(bits); cx_throw("Corrupted tiled TIFF file!"); } if (colb + tw > imagew) { uint32 owidth = imagew - colb; uint32 oskew = tilew - owidth; TileToStrip(bufp + colb, tilebuf, nrow, owidth, oskew + iskew, oskew ); } else { TileToStrip(bufp + colb, tilebuf, nrow, tilew, iskew, 0); } colb += tilew; } } else { if (TIFFReadEncodedStrip(m_tif, TIFFComputeStrip(m_tif, ys, 0), (bits16? bits16 : bits), nrow * (bits16 ? line16 : line)) == -1) { // * VK #ifdef NOT_IGNORE_CORRUPTED free(bits); if (bits16) free(bits16); // + VK cx_throw("Corrupted TIFF file!"); #else break; #endif } } for (y = 0; y < nrow; y++) { int32_t offset=(nrow-y-1)*line; if ((bitspersample==16) && !BIG_palette) { // * VK int32_t offset16 = (nrow-y-1)*line16; // + VK if (bits16) { // + VK + #ifdef FIX_16BPP_DARKIMG int32_t the_shift; uint8_t hi_byte, hi_max=0; uint32_t xi; for (xi=0;xi<(uint32)line;xi++) { hi_byte = bits16[xi*2+offset16+1]; if(hi_byte>hi_max) hi_max = hi_byte; } the_shift = (hi_max == 0) ? 8 : 0; if (!the_shift) while( ! (hi_max & 0x80) ) { the_shift++; hi_max <<= 1; } row_shifts[height-ys-nrow+y] = the_shift; the_shift = 8 - the_shift; for (xi=0;xi<(uint32)line;xi++) bits[xi+offset]= ((bits16[xi*2+offset16+1]<<8) | bits16[xi*2+offset16]) >> the_shift; #else for (uint32_t xi=0;xi<(uint32)line;xi++) bits[xi+offset]=bits16[xi*2+offset16+1]; #endif } else { for (uint32_t xi=0;xi<width;xi++) bits[xi+offset]=bits[xi*2+offset+1]; } } if (samplesperpixel==1) { if (BIG_palette) if (bits16) { int32_t offset16 = (nrow-y-1)*line16; // + VK MoveBitsPal( info.pImage + info.dwEffWidth * (height-ys-nrow+y), bits16 + offset16, width, bitspersample, pal ); } else MoveBitsPal( info.pImage + info.dwEffWidth * (height-ys-nrow+y), bits + offset, width, bitspersample, pal ); else if ((bitspersample == head.biBitCount) || (bitspersample == 16)) //simple 8bpp, 4bpp image or 16bpp memcpy(info.pImage+info.dwEffWidth*(height-ys-nrow+y),bits+offset,min((unsigned)line, info.dwEffWidth)); else MoveBits( info.pImage + info.dwEffWidth * (height-ys-nrow+y), bits + offset, width, bitspersample ); } else if (samplesperpixel==2) { //8bpp image with alpha layer int32_t xi=0; int32_t ii=0; int32_t yi=height-ys-nrow+y; #if CXIMAGE_SUPPORT_ALPHA if (!pAlpha) AlphaCreate(); // + VK #endif //CXIMAGE_SUPPORT_ALPHA while (ii<line){ SetPixelIndex(xi,yi,bits[ii+offset]); #if CXIMAGE_SUPPORT_ALPHA AlphaSet(xi,yi,bits[ii+offset+1]); #endif //CXIMAGE_SUPPORT_ALPHA ii+=2; xi++; if (xi>=(int32_t)width){ yi--; xi=0; } } } else { //photometric==PHOTOMETRIC_CIELAB if (head.biBitCount!=24){ //fix image Create(width,height,24,CXIMAGE_FORMAT_TIF); #if CXIMAGE_SUPPORT_ALPHA if (samplesperpixel==4) AlphaCreate(); #endif //CXIMAGE_SUPPORT_ALPHA } int32_t xi=0; uint32 ii=0; int32_t yi=height-ys-nrow+y; RGBQuad c; int32_t l,a,b,bitsoffset; double p,cx,cy,cz,cr,cg,cb; while (ii</*line*/width){ // * VK bitsoffset = ii*samplesperpixel+offset; l=bits[bitsoffset]; a=bits[bitsoffset+1]; b=bits[bitsoffset+2]; if (a>127) a-=256; if (b>127) b-=256; // lab to xyz p = (l/2.55 + 16) / 116.0; cx = pow( p + a * 0.002, 3); cy = pow( p, 3); cz = pow( p - b * 0.005, 3); // white point cx*=0.95047; //cy*=1.000; cz*=1.0883; // xyz to rgb cr = 3.240479 * cx - 1.537150 * cy - 0.498535 * cz; cg = -0.969256 * cx + 1.875992 * cy + 0.041556 * cz; cb = 0.055648 * cx - 0.204043 * cy + 1.057311 * cz; if ( cr > 0.00304 ) cr = 1.055 * pow(cr,0.41667) - 0.055; else cr = 12.92 * cr; if ( cg > 0.00304 ) cg = 1.055 * pow(cg,0.41667) - 0.055; else cg = 12.92 * cg; if ( cb > 0.00304 ) cb = 1.055 * pow(cb,0.41667) - 0.055; else cb = 12.92 * cb; c.rgbRed =(uint8_t)max(0,min(255,(int32_t)(cr*255))); c.rgbGreen=(uint8_t)max(0,min(255,(int32_t)(cg*255))); c.rgbBlue =(uint8_t)max(0,min(255,(int32_t)(cb*255))); SetPixelColor(xi,yi,c); #if CXIMAGE_SUPPORT_ALPHA if (samplesperpixel==4) AlphaSet(xi,yi,bits[bitsoffset+3]); #endif //CXIMAGE_SUPPORT_ALPHA ii++; xi++; if (xi>=(int32_t)width){ yi--; xi=0; } } } } } free(bits); if (bits16) free(bits16); #ifdef FIX_16BPP_DARKIMG if (row_shifts && (samplesperpixel == 1) && (bitspersample==16) && !BIG_palette) { // 1. calculate maximum necessary shift int32_t min_row_shift = 8; for( y=0; y<height; y++ ) { if (min_row_shift > row_shifts[y]) min_row_shift = row_shifts[y]; } // 2. for rows having less shift value, correct such rows: for( y=0; y<height; y++ ) { if (min_row_shift < row_shifts[y]) { int32_t need_shift = row_shifts[y] - min_row_shift; uint8_t* data = info.pImage + info.dwEffWidth * y; for( x=0; x<width; x++, data++ ) *data >>= need_shift; } }
static int cvt_whole_image( TIFF *in, TIFF *out ) { uint32* raster; /* retrieve RGBA image */ uint32 width, height; /* image width & height */ uint32 row; uint32 *wrk_line; TIFFGetField(in, TIFFTAG_IMAGEWIDTH, &width); TIFFGetField(in, TIFFTAG_IMAGELENGTH, &height); rowsperstrip = TIFFDefaultStripSize(out, rowsperstrip); TIFFSetField(out, TIFFTAG_ROWSPERSTRIP, rowsperstrip); raster = (uint32*)_TIFFmalloc(width * height * sizeof (uint32)); if (raster == 0) { TIFFError(TIFFFileName(in), "No space for raster buffer"); return (0); } /* Read the image in one chunk into an RGBA array */ if (!TIFFReadRGBAImage(in, width, height, raster, 0)) { _TIFFfree(raster); return (0); } /* For some reason the TIFFReadRGBAImage() function chooses the lower left corner as the origin. Vertically mirror scanlines. */ wrk_line = (uint32*)_TIFFmalloc(width * sizeof (uint32)); if (wrk_line == 0) { TIFFError(TIFFFileName(in), "No space for raster scanline buffer"); return (0); } for( row = 0; row < height / 2; row++ ) { uint32 *top_line, *bottom_line; top_line = raster + width * row; bottom_line = raster + width * (height-row-1); _TIFFmemcpy(wrk_line, top_line, 4*width); _TIFFmemcpy(top_line, bottom_line, 4*width); _TIFFmemcpy(bottom_line, wrk_line, 4*width); } _TIFFfree( wrk_line ); /* Write out the result in strips */ for( row = 0; row < height; row += rowsperstrip ) { uint32* raster_strip; int rows_to_write; raster_strip = raster + row * width; if( row + rowsperstrip > height ) rows_to_write = height - row; else rows_to_write = rowsperstrip; if( TIFFWriteEncodedStrip( out, row / rowsperstrip, raster_strip, 4 * rows_to_write * width ) == -1 ) { _TIFFfree( raster ); return 0; } } _TIFFfree( raster ); return 1; }