// ------------------------------------------------------------ // imageio.c // // Reading writing tiff images // // 12.03.2005, J.Ahrensfeld // ------------------------------------------------------------ #include #include #include #include #include #include "types.h" #include "colortypes.h" #include "imageio.h" #define jmalloc malloc #define jfree free // ------------------------------------------------------------ double smin(double v1, double v2) { if (v1 < v2) return v1; return v2; } // ------------------------------------------------------------ double smax(double v1, double v2) { if (v1 > v2) return v1; return v2; } // ------------------------------------------------------------ void ImageInit(image_t *pObj, int im_width, int im_height, int num_ch) { pObj->im_height = im_height; pObj->im_width = im_width; pObj->num_ch = num_ch; pObj->num_pixel = im_height*im_width; pObj->pColor_data = NULL; if (pObj->num_pixel && pObj->num_ch) { pObj->pColor_data = (double*)jmalloc(pObj->num_pixel*num_ch*sizeof(double)); memset(pObj->pColor_data, 0, pObj->num_pixel*num_ch*sizeof(double)); } } // ------------------------------------------------------------ void ImageFree(image_t *pObj) { pObj->im_height = 0; pObj->im_width = 0; pObj->num_pixel = 0; pObj->num_ch = 0; if (pObj->pColor_data) jfree(pObj->pColor_data); pObj->pColor_data = NULL; } // ------------------------------------------------------------ void ImageCopy(image_t *pSrc, image_t *pDst) { pDst->im_height = pSrc->im_height; pDst->im_width = pSrc->im_width; pDst->num_pixel = pSrc->num_pixel; pDst->num_ch = pSrc->num_ch; if (!pDst->pColor_data) pDst->pColor_data = (double*)jmalloc(pSrc->num_ch*pSrc->num_pixel*sizeof(double)); memcpy(pDst->pColor_data, pSrc->pColor_data, pSrc->num_ch*pSrc->num_pixel*sizeof(double)); } UINT32 ImageGetPixelData(image_t *pObj, double *pData) { int i; for (i=0; i < pObj->num_pixel*pObj->num_ch; i++) { pData[i] = pObj->pColor_data[i]; } return i; } UINT32 ImageGetTile(image_t *pObj, UINT32 u, UINT32 v, UINT32 w, UINT32 h, double *pData) { int i, j, k, x, y; for (i=0; i < h; i++) { y = pObj->im_width*pObj->num_ch*(v + i); for (j=0; j < w; j++) { x = pObj->num_ch*(u + j); for (k=0; k < pObj->num_ch; k++) *(pData++) = pObj->pColor_data[x + y + k]; } } return w*h*pObj->num_ch; } UINT32 ImageSetTile(image_t *pObj, UINT32 u, UINT32 v, UINT32 w, UINT32 h, double *pData) { int i, j, k, x, y; for (i=0; i < h; i++) { y = pObj->im_width*pObj->num_ch*(v + i); for (j=0; j < w; j++) { x = pObj->num_ch*(u + j); for (k=0; k < pObj->num_ch; k++) pObj->pColor_data[x + y + k] = *(pData++); } } return w*h*pObj->num_ch; } // ------------------------------------------------------------ int ImageLoadTiff(image_t *pObj, char *filename) { TIFF *pTifComp; UINT16 config, nBits, nSamples, photometric; UINT32 i, im_width, im_height, scan_size, num_color_ch; double k_norm; double c; UINT8 *pImage_comp8; int status; ImageFree(pObj); pTifComp = TIFFOpen(filename,"r"); if (!pTifComp) { fprintf(stderr,"Unable to open input file %s\n",filename); return -1; } status = TIFFGetField(pTifComp, TIFFTAG_IMAGEWIDTH, &im_width); status = TIFFGetField(pTifComp, TIFFTAG_IMAGELENGTH, &im_height); status = TIFFGetField(pTifComp, TIFFTAG_BITSPERSAMPLE, &nBits); status = TIFFGetField(pTifComp, TIFFTAG_PLANARCONFIG, &config); status = TIFFGetField(pTifComp, TIFFTAG_PHOTOMETRIC, &photometric); status = TIFFGetField(pTifComp, TIFFTAG_SAMPLESPERPIXEL, &nSamples); num_color_ch = (UINT32)nSamples; pObj->im_height = im_height; pObj->im_width = im_width; pObj->num_pixel = im_height*im_width; pObj->num_ch = num_color_ch; pObj->pColor_data = (double*)jmalloc(num_color_ch*pObj->num_pixel*sizeof(double)); scan_size = TIFFScanlineSize(pTifComp); pImage_comp8 = (UINT8*)_TIFFmalloc(scan_size*im_height*sizeof(UINT8)); for (i=0; i < im_height; i++) status = TIFFReadScanline(pTifComp, &pImage_comp8[i*scan_size], i, 0); TIFFClose(pTifComp); k_norm = 1.0/(pow(2.0,nBits)-1); for (i=0; i < num_color_ch*im_width*im_height; i++) { c = k_norm*(double)pImage_comp8[i]; pObj->pColor_data[i] = c; } _TIFFfree(pImage_comp8); return 0; } // ------------------------------------------------------------ int ImageSaveTiff(image_t *pObj, char *filename) { TIFF *pTifComp; ttag_t config, nBits, nSamples, photometric, extra_sample_info; UINT32 i, im_width, im_height, scan_size; double k_norm; double c, a; UINT8 *pImage_comp8; int status; pTifComp = TIFFOpen(filename,"w"); if (!pTifComp) { fprintf(stderr,"Unable to open input file %s\n",filename); return -1; } nBits = 8; im_height = pObj->im_height; im_width = pObj->im_width; config = PLANARCONFIG_CONTIG; status = TIFFSetField(pTifComp, TIFFTAG_IMAGEWIDTH, im_width); status = TIFFSetField(pTifComp, TIFFTAG_IMAGELENGTH, im_height); status = TIFFSetField(pTifComp, TIFFTAG_ROWSPERSTRIP, im_height); status = TIFFSetField(pTifComp, TIFFTAG_BITSPERSAMPLE, nBits); status = TIFFSetField(pTifComp, TIFFTAG_PLANARCONFIG, config); status = TIFFSetField(pTifComp, TIFFTAG_ARTIST, "JDI, J. Ahrensfeld"); switch(pObj->num_ch) { case 3: case 4: photometric = PHOTOMETRIC_RGB; status = TIFFSetField(pTifComp, TIFFTAG_SAMPLESPERPIXEL, pObj->num_ch); scan_size = pObj->num_ch*im_width; break; case 1: photometric = PHOTOMETRIC_MINISBLACK; status = TIFFSetField(pTifComp, TIFFTAG_SAMPLESPERPIXEL, 1); scan_size = im_width; break; default: return -1; } status = TIFFSetField(pTifComp, TIFFTAG_PHOTOMETRIC, photometric); nSamples = (ttag_t)pObj->num_ch; extra_sample_info = 0; if (nSamples == 4) { extra_sample_info = EXTRASAMPLE_ASSOCALPHA; status = TIFFSetField(pTifComp, TIFFTAG_EXTRASAMPLES, 1, &extra_sample_info); } //TIFFTAG_IMAGEDESCRIPTION //TIFFTAG_SOFTWARE 305 /* name & release */ //TIFFTAG_DATETIME 306 /* creation date and time */ pImage_comp8 = (UINT8*)jmalloc(nSamples*im_width*im_height*sizeof(UINT8)); k_norm = pow(2.0,nBits)-1; if (nSamples == 4) { for (i=0; i < im_width*im_height; i++) { a = pObj->pColor_data[nSamples*i+3]; a = smin(smax(a,0),1); c = pObj->pColor_data[nSamples*i+0]; c = a*smin(smax(c,0),1); pImage_comp8[nSamples*i+0] = (UINT8)(k_norm*c); c = pObj->pColor_data[nSamples*i+1]; c = a*smin(smax(c,0),1); pImage_comp8[nSamples*i+1] = (UINT8)(k_norm*c); c = pObj->pColor_data[nSamples*i+2]; c = a*smin(smax(c,0),1); pImage_comp8[nSamples*i+2] = (UINT8)(k_norm*c); pImage_comp8[nSamples*i+3] = (UINT8)(k_norm*a); } } else { for (i=0; i < nSamples*im_width*im_height; i++) { c = pObj->pColor_data[i]; c = smin(smax(c,0),1); pImage_comp8[i] = (UINT8)(k_norm*c); } } for (i=0; i < im_height; i++) { status = TIFFWriteScanline(pTifComp, &pImage_comp8[(im_height-i-1)*scan_size], i, 0); if (status < 0) TIFFError("ImageSaveTiff", "%s", "Hallo") ; } jfree(pImage_comp8); TIFFClose(pTifComp); return 0; } void ImageSetPixel(image_t *pObj, UINT32 u, UINT32 v, rgba_t color) { UINT32 offset; rgb_t *pRGB; rgba_t *pRGBA; pRGB = (rgb_t*)pObj->pColor_data; pRGBA = (rgba_t*)pObj->pColor_data; if (pObj->num_ch == 4) { if ((u < pObj->im_width) && (v < pObj->im_height)) { offset = (UINT32)(pObj->im_width*v); pRGBA[u+offset][0] = color[0]; pRGBA[u+offset][1] = color[1]; pRGBA[u+offset][2] = color[2]; pRGBA[u+offset][3] = color[3]; } } else { if ((u < pObj->im_width) && (v < pObj->im_height)) { offset = (UINT32)(pObj->im_width*v); pRGB[u+offset][0] = color[0]; pRGB[u+offset][1] = color[1]; pRGB[u+offset][2] = color[2]; } } }