static void raster_special(int key, int x, int y) { (void) x; (void) y; switch (key) { case GLUT_KEY_PAGE_UP: /* previous logical image */ if (TIFFCurrentDirectory(tif) > 0) { if (TIFFSetDirectory(tif, TIFFCurrentDirectory(tif)-1)) { initImage(); setWindowSize(); } } else { TIFFRGBAImageEnd(&img); prevImage(); initImage(); setWindowSize(); } break; case GLUT_KEY_PAGE_DOWN: /* next logical image */ if (!TIFFLastDirectory(tif)) { if (TIFFReadDirectory(tif)) { initImage(); setWindowSize(); } } else { TIFFRGBAImageEnd(&img); nextImage(); initImage(); setWindowSize(); } break; case GLUT_KEY_HOME: /* 1st image in current file */ if (TIFFSetDirectory(tif, 0)) { TIFFRGBAImageEnd(&img); initImage(); setWindowSize(); } break; case GLUT_KEY_END: /* last image in current file */ TIFFRGBAImageEnd(&img); while (!TIFFLastDirectory(tif)) TIFFReadDirectory(tif); initImage(); setWindowSize(); break; } glutPostRedisplay(); }
// Reads Tiff Images RGBAImage* RGBAImage::ReadTiff(char *filename) { RGBAImage *fimg = 0; TIFF* tif = TIFFOpen(filename, "r"); char emsg[1024]; if (tif) { TIFFRGBAImage img; if (TIFFRGBAImageBegin(&img, tif, 0, emsg)) { size_t npixels; uint32* raster; npixels = img.width * img.height; raster = (uint32*) _TIFFmalloc(npixels * sizeof (uint32)); if (raster != NULL) { if (TIFFRGBAImageGet(&img, raster, img.width, img.height)) { // result is in ABGR fimg = new RGBAImage(img.width, img.height); for (int y = 0; y < img.height; y++) { for (int x = 0; x < img.width; x++) { fimg->Set(x,y, raster[x + y * img.width]); } } } _TIFFfree(raster); } } TIFFRGBAImageEnd(&img); } else { TIFFError(filename, emsg); } return fimg; }
static UncompressedImage LoadTiff(TiffLoader &tiff) { TIFFRGBAImage img; tiff.RGBAImageBegin(img); AtScopeExit(&img) { TIFFRGBAImageEnd(&img); }; return LoadTiff(img); }
static void cleanup_and_exit(void) { TIFFRGBAImageEnd(&img); if (filelist != NULL) _TIFFfree(filelist); if (raster != NULL) _TIFFfree(raster); if (tif != NULL) TIFFClose(tif); exit(0); }
int ReadStrip(TIFF* tiff, UINT32 row, UINT32* buffer) { uint16 photometric; TIFFGetField(tiff, TIFFTAG_PHOTOMETRIC, &photometric); // To avoid dealing with YCbCr subsampling, let libtiff handle it if (photometric == PHOTOMETRIC_YCBCR) { TIFFRGBAImage img; char emsg[1024] = ""; UINT32 rows_per_strip, rows_to_read; int ok; TIFFGetFieldDefaulted(tiff, TIFFTAG_ROWSPERSTRIP, &rows_per_strip); if ((row % rows_per_strip) != 0) { TRACE(("Row passed to ReadStrip() must be first in a strip.")); return -1; } if (TIFFRGBAImageOK(tiff, emsg) && TIFFRGBAImageBegin(&img, tiff, 0, emsg)) { TRACE(("Initialized RGBAImage\n")); img.req_orientation = ORIENTATION_TOPLEFT; img.row_offset = row; img.col_offset = 0; rows_to_read = min(rows_per_strip, img.height - row); TRACE(("rows to read: %d\n", rows_to_read)); ok = TIFFRGBAImageGet(&img, buffer, img.width, rows_to_read); TIFFRGBAImageEnd(&img); } else { ok = 0; } if (ok == 0) { TRACE(("Decode Error, row %d; msg: %s\n", row, emsg)); return -1; } return 0; } if (TIFFReadEncodedStrip(tiff, TIFFComputeStrip(tiff, row, 0), (tdata_t)buffer, -1) == -1) { TRACE(("Decode Error, strip %d\n", TIFFComputeStrip(tiff, row, 0))); return -1; } return 0; }
PVOID ReadTIFF ( LPCTSTR lpszPath ) { void* pDIB = 0; TIFFErrorHandler wh; wh = TIFFSetWarningHandler(MyWarningHandler); if (ChkTIFF(lpszPath)) { TIFF* tif = TIFFOpen(lpszPath, "r"); if (tif) { char emsg[1024]; if (TIFFRGBAImageOK(tif, emsg)) { TIFFDibImage img; char emsg[1024]; if (TIFFRGBAImageBegin(&img.tif, tif, -1, emsg)) { size_t npixels; uint32* raster; DibInstallHack(&img); npixels = img.tif.width * img.tif.height; raster = (uint32*) _TIFFmalloc(npixels * sizeof (uint32)); if (raster != NULL) { if (TIFFRGBAImageGet(&img.tif, raster, img.tif.width, img.tif.height)) { pDIB = TIFFRGBA2DIB(&img, raster); } } _TIFFfree(raster); } TIFFRGBAImageEnd(&img.tif); } else { TRACE("Unable to open image(%s): %s\n", lpszPath, emsg ); } TIFFClose(tif); } } TIFFSetWarningHandler(wh); return pDIB; }
/* * Read the specified image into an ABGR-format raster. */ int TIFFReadRGBAImage(TIFF* tif, uint32 rwidth, uint32 rheight, uint32* raster, int stop) { char emsg[1024]; TIFFRGBAImage img; int ok; if (TIFFRGBAImageBegin(&img, tif, stop, emsg)) { /* XXX verify rwidth and rheight against width and height */ ok = TIFFRGBAImageGet(&img, raster+(rheight-img.height)*rwidth, rwidth, img.height); TIFFRGBAImageEnd(&img); } else { TIFFError(TIFFFileName(tif), emsg); ok = 0; } return (ok); }
void PLTIFFDecoder::doHiColor (TIFF * tif, PLBmpBase * pBmp, uint16 SamplePerPixel) { int ok; PLULONG x, y; TIFFRGBAImage img; char emsg[1024]; PLBYTE * pBits; ok = TIFFRGBAImageBegin(&img, tif, 0, emsg); if (ok == 0) { raiseError (PL_ERRWRONG_SIGNATURE, "TIFF subformat not supported."); } //bool bHasAlpha = pBmp->HasAlpha(); PLASSERT (int(img.width) == pBmp->GetWidth()); PLASSERT (int(img.height) == pBmp->GetHeight()); PLASSERT (pBmp->GetBitsPerPixel() == 32); pBits = new PLBYTE [img.width*img.height*4]; if (pBits == NULL) raiseError (PL_ERRNO_MEMORY, "Out of memory allocating TIFF buffer."); // Hack for photoshop alpha channel support if (SamplePerPixel == 4 && img.bitspersample == 8 && img.photometric == 2) { img.put.contig = putRGBAAcontig8bittile; } ok = TIFFRGBAImageGet(&img, (uint32 *) pBits, img.width, img.height); if (!ok) { TIFFRGBAImageEnd(&img); raiseError (PL_ERRWRONG_SIGNATURE, m_szLastErr); } PLPixel32 ** pLineArray = pBmp->GetLineArray32(); // Correct the byte ordering. This could be replaced by appropriate // putRGBAcontig... routines. for (y=0; y<img.height; y++) { PLBYTE * pSrc = pBits+(img.height-y-1)*img.width*4; PLPixel32 * pPixel = pLineArray[y]; for (x=0; x<img.width; x++) { #ifdef WORDS_BIGENDIAN pPixel->Set (*(pSrc+3), *(pSrc+2), *(pSrc+1), *(pSrc)); #else pPixel->Set (*pSrc, *(pSrc+1), *(pSrc+2), *(pSrc+3)); #endif pPixel++; pSrc += 4; } } // Clean up. delete [] pBits; TIFFRGBAImageEnd(&img); }
void WCTextureManager::LoadTexture(WSTexture *texObj) { //Set the warning handler TIFFSetWarningHandler(_TIFFWarning); //Create the image from file std::string filename = _ResourceDirectory() + "\\" + texObj->_name + ".tiff"; TIFF *tif; try { tif = TIFFOpen(filename.c_str(), "r"); } catch (...) { CLOGGER_ERROR(WCLogManager::RootLogger(), "WCTextureManager::LoadTexture - Caught an exception."); } if (tif == NULL){ CLOGGER_ERROR(WCLogManager::RootLogger(), "WCTextureManager::LoadTexture - Not able to load: " << texObj->_name); return; } //Read the tif image data into a buffer char emsg[1024]; TIFFRGBAImage img; TIFFRGBAImageBegin(&img, tif, 1, emsg); if(WCAdapter::HasGL15()) { texObj->_texture_width = img.width; texObj->_texture_height = img.height; } else { // use pow(2, n) for texture width and height for(texObj->_texture_width = 1; texObj->_texture_width < (GLint)img.width; texObj->_texture_width *= 2){} for(texObj->_texture_height = 1; texObj->_texture_height < (GLint)img.height; texObj->_texture_height *= 2){} } //Get all of the raster data size_t npixels = texObj->_texture_width * texObj->_texture_height; uint32 *data = new uint32[npixels]; TIFFReadRGBAImageOriented(tif, texObj->_texture_width, texObj->_texture_height, data, ORIENTATION_TOPLEFT, 0); TIFFRGBAImageEnd(&img); //Enable texturing glEnable(texObj->_target); //Generate a new texture glGenTextures (1, &(texObj->_id)); glBindTexture (texObj->_target, texObj->_id); //Set the min/mag filters glTexParameteri(texObj->_target, GL_TEXTURE_MIN_FILTER, texObj->_minFilter); glTexParameteri(texObj->_target, GL_TEXTURE_MAG_FILTER, texObj->_magFilter); glTexParameteri(texObj->_target, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameteri(texObj->_target, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexImage2D(texObj->_target, 0, 4, texObj->_texture_width, texObj->_texture_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); //Clean up glDisable(texObj->_target); //Check for errors GLenum err = glGetError(); if (err != GL_NO_ERROR) { CLOGGER_ERROR(WCLogManager::RootLogger(), "WCTextureManager::LoadTexture - At clean up on image: " << texObj->_name); } //Get the object width and height texObj->_width = (GLfloat)img.width; texObj->_height = (GLfloat)img.height; //Clean up delete data; }
int main(int argc, char **argv) { TIFF *tif; char emsg[1024]; int i; glutInit(&argc, argv); for (i = 1; i < argc; i++) { if (!strcmp(argv[i], "-sb")) { doubleBuffer = 0; } else { filename = argv[i]; } } if (filename == NULL) { fprintf(stderr, "usage: textiff [GLUT-options] [-sb] TIFF-file\n"); exit(1); } tif = TIFFOpen(filename, "r"); if (tif == NULL) { fprintf(stderr, "Problem showing %s\n", filename); exit(1); } if (TIFFRGBAImageBegin(&img, tif, 0, emsg)) { npixels = (tsize_t) (img.width * img.height); raster = (uint32 *) _TIFFmalloc(npixels * (tsize_t) sizeof(uint32)); if (raster != NULL) { if (TIFFRGBAImageGet(&img, raster, img.width, img.height) == 0) { TIFFError(filename, emsg); exit(1); } } TIFFRGBAImageEnd(&img); } else { TIFFError(filename, emsg); exit(1); } if (doubleBuffer) { glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE); } else { glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE); } glutInitWindowSize((int) img.width, (int) img.height); glutCreateWindow("textiff"); glutDisplayFunc(display); glutSpecialFunc(special); #ifdef GL_EXT_abgr if (glutExtensionSupported("GL_EXT_abgr")) hasABGR = 1; #else hasABGR = 0; #endif /* If cannot directly display ABGR format, we need to reverse the component ordering in each pixel. :-( */ if (!hasABGR) { int i; for (i = 0; i < npixels; i++) { register unsigned char *cp = (unsigned char *) &raster[i]; int t; t = cp[3]; cp[3] = cp[0]; cp[0] = t; t = cp[2]; cp[2] = cp[1]; cp[1] = t; } } /* OpenGL's default unpack (and pack) alignment is 4. In the case of the data returned by libtiff which is already aligned on 32-bit boundaries, setting the pack to 1 isn't strictly necessary. */ glPixelStorei(GL_UNPACK_ALIGNMENT, 1); gluOrtho2D(-1, 1, -1, 1); /* Linear sampling within a mipmap level. */ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); glEnable(GL_TEXTURE_2D); /* A TIFF file could be any size; OpenGL textures are allowed to have a width and height that is a power of two (32, 64, 128, etc.). To maximize the use of available texture memory, we scale the image to gluScaleImage to the next larger power of 2 width or height dimension (not exceeding 512, don't want to use too much texture memory!). This rescaling can result in a bit of image bluring because of the resampling done by gluScaleImage. An alternative would be to change the texture coordinates to only use a portion texture area. */ tw = 1 << (int) ceil(log(img.width) / log(2.0)); th = 1 << (int) ceil(log(img.height) / log(2.0)); if (tw > 512) tw = 512; if (th > 512) th = 512; texture = (uint32 *) malloc(sizeof(GLubyte) * 4 * tw * th); #ifdef GL_EXT_abgr #define APPROPRIATE_FORMAT (hasABGR ? GL_ABGR_EXT : GL_RGBA) #else #define APPROPRIATE_FORMAT GL_RGBA #endif gluScaleImage(APPROPRIATE_FORMAT, (GLsizei) img.width, (GLsizei) img.height, GL_UNSIGNED_BYTE, raster, tw, th, GL_UNSIGNED_BYTE, texture); _TIFFfree(raster); /* Build mipmaps for the texture image. Since we are not scaling the image (we easily could by calling glScalef), creating mipmaps is not really useful, but it is done just to show how easily creating mipmaps is. */ gluBuild2DMipmaps(GL_TEXTURE_2D, 4, tw, th, APPROPRIATE_FORMAT, GL_UNSIGNED_BYTE, texture); /* Use a gray background so TIFF images with black backgrounds will show against textiff's background. */ glClearColor(0.2, 0.2, 0.2, 1.0); glutMainLoop(); return 0; /* ANSI C requires main to return int. */ }
int main(int argc, char **argv) { TIFF *tif; char emsg[1024]; int i; glutInit(&argc, argv); for (i = 1; i < argc; i++) { if (!strcmp(argv[i], "-sb")) { doubleBuffer = 0; } else { filename = argv[i]; } } if (filename == NULL) { fprintf(stderr, "usage: showtiff [GLUT-options] [-sb] TIFF-file\n"); exit(1); } tif = TIFFOpen(filename, "r"); if (tif == NULL) { fprintf(stderr, "Problem showing %s\n", filename); exit(1); } if (TIFFRGBAImageBegin(&img, tif, 0, emsg)) { npixels = (tsize_t) (img.width * img.height); raster = (uint32 *) _TIFFmalloc(npixels * (tsize_t) sizeof(uint32)); if (raster != NULL) { if (TIFFRGBAImageGet(&img, raster, img.width, img.height) == 0) { TIFFError(filename, emsg); exit(1); } } TIFFRGBAImageEnd(&img); } else { TIFFError(filename, emsg); exit(1); } if (doubleBuffer) { glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE); } else { glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE); } imgwidth = (int) img.width; imgheight = (int) img.height; glutInitWindowSize(imgwidth, imgheight); glutCreateWindow("showtiff"); glutReshapeFunc(reshape); glutDisplayFunc(display); glutMouseFunc(mouse); glutMotionFunc(motion); #ifdef GL_EXT_abgr if (glutExtensionSupported("GL_EXT_abgr")) { hasABGR = 1; } #endif #ifdef GL_EXT_convolution if (glutExtensionSupported("GL_EXT_convolution")) { hasConvolve = 1; } else { while (glGetError() != GL_NO_ERROR); /* Clear any OpenGL errors. */ /* The following glDisable would be a no-op whether done on a freshly initialized OpenGL context whether convolution is supported or not. The only difference should be an OpenGL error should be reported if the GL_CONVOLUTION_2D_EXT is not understood (ie, convolution is not supported at all). */ glDisable(GL_CONVOLUTION_2D_EXT); if (glGetError() == GL_NO_ERROR) { /* RealityEngine only partially implements the convolve extension and hence does not advertise the extension in its extension string (See MACHINE DEPENDENCIES section of the glConvolutionFilter2DEXT man page). We limit this program to use only the convolve functionality supported by RealityEngine so we test if OpenGL lets us enable convolution without an error (the indication that convolution is partially supported). */ hasConvolve = 1; } /* Clear any further OpenGL errors (hopefully there should have only been one or zero though). */ while (glGetError() != GL_NO_ERROR); } #endif #ifdef GL_SGI_color_matrix if (glutExtensionSupported("GL_SGI_color_matrix")) { hasColorMatrix = 1; } #endif /* If cannot directly display ABGR format, we need to reverse the component ordering in each pixel. :-( */ if (!hasABGR) { int i; for (i = 0; i < npixels; i++) { register unsigned char *cp = (unsigned char *) &raster[i]; int t; t = cp[3]; cp[3] = cp[0]; cp[0] = t; t = cp[2]; cp[2] = cp[1]; cp[1] = t; } } glPixelStorei(GL_UNPACK_ALIGNMENT, 1); initKernels(); glutCreateMenu(option); glutAddMenuEntry("Normal", 1); #ifdef GL_EXT_convolution if (hasConvolve) { glutAddMenuEntry("7x7 Blur", 2); glutAddMenuEntry("3x3 Sharpen", 3); glutAddMenuEntry("3x3 Edge Detect", 4); } #endif #ifdef GL_SGI_color_matrix if (hasColorMatrix) { glutAddMenuEntry("Toggle Luminance/RGB", 5); } #endif glutAddMenuEntry("Quit", 666); glutAttachMenu(GLUT_RIGHT_BUTTON); /* Use a gray background so TIFF images with black backgrounds will show against textiff's background. */ glClearColor(0.2, 0.2, 0.2, 1.0); glutMainLoop(); return 0; /* ANSI C requires main to return int. */ }