Main Page | Data Structures | Directories | File List | Data Fields | Globals

Sadie_Image.c

Go to the documentation of this file.
00001 
00022 /* This file is part of tclSadie.
00023 
00024    tclSadie is free software; you can redistribute it and/or modify it
00025    under the terms of the GNU General Public License as published by
00026    the Free Software Foundation; either version 2 of the License, or
00027    (at your option) any later version.
00028 
00029    tclSadie is distributed in the hope that it will be useful, but
00030    WITHOUT ANY WARRANTY; without even the implied warranty of
00031    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00032    General Public License for more details.
00033 
00034    You should have received a copy of the GNU General Public License
00035    along with tclSadie; if not, write to the Free Software Foundation,
00036    Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.  */
00037 
00038 #if HAVE_CONFIG_H
00039 #include <config.h>
00040 #endif /* HAVE_CONFIG_H */
00041 #include <tcl.h>
00042 #include <tk.h>
00043 #include <string.h>
00044 #include <sadie.h>
00045 #include "tclsadie.h"
00046 
00047 /* Forward declaration of the SADIE string match callback. */
00048 static int
00049 MatchSADIE (Tcl_Obj * data, Tcl_Obj * format,
00050             int * widthPtr, int * heightPtr, Tcl_Interp * interp);
00051 
00052 /* Forward declaration of the SADIE string input callback. */
00053 static int
00054 ReadSADIE  (Tcl_Interp * interp, Tcl_Obj * data, Tcl_Obj * format,
00055             Tk_PhotoHandle imageHandle,
00056             int destX, int destY, int width, int height,
00057             int srcX, int srcY);
00058 
00059 /* Forward declaration of the SADIE file output callback. */
00060 static int
00061 WriteSADIE (Tcl_Interp * interp, const char * fileName,
00062             Tcl_Obj * format, Tk_PhotoImageBlock * blockPtr);
00063 
00065 Tk_PhotoImageFormat tkImgFmtSADIE =
00066   {
00067     "sadie", 
00068     NULL, 
00069     MatchSADIE, 
00070     NULL, 
00071     ReadSADIE, 
00072     WriteSADIE, 
00073     NULL  
00074   };
00075 
00088 static int
00089 MatchSADIE (Tcl_Obj *data, Tcl_Obj *format, int *widthPtr,
00090             int *heightPtr, Tcl_Interp *interp)
00091 {
00092   IMAGE *img;
00093 
00094   if ((GetSadieImageFromObj (data, &img) != TCL_OK) || (!CHECKIMG (img)))
00095     return 0;
00096   else
00097     {
00098       *widthPtr = img->npix;
00099       *heightPtr = img->nlin;
00100       return 1;
00101     }
00102 }
00103 
00108 static const double stretchMin = 0;
00109 static const double stretchMax = 255;
00110 static const double stretchTol = 1e-5;
00125 static void
00126 fill_bytes (void *pixelPtr, PIXEL corner, size_t n)
00127 {
00128   double scaled;
00129 
00130   scaled = ((corner <= SMIN)
00131             ? 0
00132             : (((corner >= SMAX)
00133                 ? SMAX
00134                 : corner)
00135                - SMIN));
00136   memset (pixelPtr,
00137           (int)(floor ((scaled * (stretchMax - stretchMin))
00138                        / (SMAX - SMIN))),
00139           n);
00140 }
00141 
00149 static void
00150 stretch_rgb (unsigned char *pixelPtr, IMAGE *img)
00151 {
00152   size_t j, k;
00153   double factor, offset;
00154 
00155   factor = (stretchMax - stretchMin) / (double)(img->gmax - img->gmin);
00156   offset = stretchMin - (img->gmin * factor);
00157   for (j = 0; j < img->nlin; j++)
00158     {
00159       for (k = 0; k < img->npix; k++)
00160         {
00161           *pixelPtr++ = (unsigned char)(factor * img->data[0][j][k] + offset);
00162           *pixelPtr++ = (unsigned char)(factor * img->data[1][j][k] + offset);
00163           *pixelPtr++ = (unsigned char)(factor * img->data[2][j][k] + offset);
00164         }
00165     }
00166 }
00167 
00175 static void
00176 transcribe_rgb (unsigned char *pixelPtr, IMAGE *img)
00177 {
00178   size_t j, k;
00179 
00180   for (j = 0; j < img->nlin; j++)
00181     {
00182       for (k = 0; k < img->npix; k++)
00183         {
00184           *pixelPtr++ = (unsigned char) img->data[0][j][k];
00185           *pixelPtr++ = (unsigned char) img->data[1][j][k];
00186           *pixelPtr++ = (unsigned char) img->data[2][j][k];
00187         }
00188     }
00189 }
00190 
00198 static void
00199 stretch_greyscale (unsigned char *pixelPtr, IMAGE *img)
00200 {
00201   size_t j, k;
00202   double factor, offset;
00203 
00204   factor = (stretchMax - stretchMin) / (double)(img->gmax - img->gmin);
00205   offset = stretchMin - (img->gmin * factor);
00206   for (j = 0; j < img->nlin; j++)
00207     {
00208       for (k = 0; k < img->npix; k++)
00209         *pixelPtr++ = (unsigned char)(factor * img->data[0][j][k] + offset);
00210     }
00211 }
00212 
00220 static void
00221 transcribe_greyscale (unsigned char *pixelPtr, IMAGE *img)
00222 {
00223   size_t j, k;
00224 
00225   for (j = 0; j < img->nlin; j++)
00226     {
00227       for (k = 0; k < img->npix; k++)
00228         *pixelPtr++ = (unsigned char) img->data[0][j][k];
00229     }
00230 }
00251 static int
00252 ReadSADIE (Tcl_Interp *interp, Tcl_Obj *data, Tcl_Obj *format,
00253            Tk_PhotoHandle imageHandle, int destX, int destY,
00254            int width, int height, int srcX, int srcY)
00255 {
00256   int option, need_stretch;
00257   size_t nbytes;
00258   Tk_PhotoImageBlock block;
00259   IMAGE *img;
00260   int err = TCL_OK;
00261   Tcl_Obj *arrayobjPtr = NULL;
00262   Tcl_Obj *indexobjPtr = NULL;
00263   Tcl_Obj *valueobjPtr = NULL;
00264 
00265   arrayobjPtr = Tcl_NewStringObj (SADIEVAR_ARRAYNAME, -1);
00266   Tcl_IncrRefCount (arrayobjPtr);
00267   indexobjPtr = Tcl_NewStringObj ("getstretched", -1);
00268   Tcl_IncrRefCount (indexobjPtr);
00269   valueobjPtr = Tcl_ObjGetVar2 (interp, arrayobjPtr, indexobjPtr, 0);
00270   if (valueobjPtr == NULL)
00271     option = 1;
00272   else
00273     {
00274       Tcl_IncrRefCount (valueobjPtr);
00275       Tcl_GetIntFromObj (interp, valueobjPtr, &option);
00276       Tcl_DecrRefCount (valueobjPtr);
00277     }
00278   Tcl_DecrRefCount (indexobjPtr);
00279   Tcl_DecrRefCount (arrayobjPtr);
00280   if (GetSadieImageFromObj (data, &img) != TCL_OK)
00281     return TCL_ERROR;
00282   else
00283     Tcl_ResetResult (interp);
00284   if (!CHECKIMG (img))
00285     {
00286       Tcl_AppendStringsToObj (Tcl_GetObjResult (interp),
00287                               "Couldn't identify SADIE image from input string.",
00288                               NULL);
00289       err = TCL_ERROR;
00290     }
00291   if ((int) img->nbnd <= 0)
00292     {
00293       Tcl_AppendStringsToObj (Tcl_GetObjResult (interp),
00294                               "Image bands not within display range.", NULL);
00295       err = TCL_ERROR;
00296     }
00297   if ((int) img->nlin <= 0)
00298     {
00299       Tcl_AppendStringsToObj (Tcl_GetObjResult (interp),
00300                               "Image lines not within display range.", NULL);
00301       err = TCL_ERROR;
00302     }
00303   if ((int) img->npix <= 0)
00304     {
00305       Tcl_AppendStringsToObj (Tcl_GetObjResult (interp),
00306                               "Image pixels not within display range.", NULL);
00307       err = TCL_ERROR;
00308     }
00309   if (err != TCL_OK)
00310     return TCL_ERROR;
00311   if (width > img->npix)
00312     width = img->npix;
00313   if (height > img->nlin)
00314     height = img->nlin;
00315   if ((width <= 0) || (height <= 0))
00316     return TCL_OK;
00317   block.width = width;
00318   block.height = height;
00319   if (img->nbnd != 3)
00320     {
00321       block.pixelSize = 1;
00322       block.offset[0] = 0;
00323       block.offset[1] = 0;
00324       block.offset[2] = 0;
00325       block.offset[3] = 0;
00326     }
00327   else
00328     {
00329       block.pixelSize = 3;
00330       block.offset[0] = 0;
00331       block.offset[1] = 1;
00332       block.offset[2] = 2;
00333       block.offset[3] = 0;
00334     }
00335   block.pitch = block.pixelSize * img->npix;
00336   nbytes = height * block.pitch;
00337   block.pixelPtr = (unsigned char *) ckalloc (nbytes);
00338   Tk_PhotoExpand(imageHandle, destX + width, destY + height);
00339   RANGE (img);
00340   need_stretch = ((option == 1)
00341                   && ((fabs (stretchMin - img->gmin) > stretchTol)
00342                       || (fabs (stretchMax - img->gmax) > stretchTol)));
00343   if (need_stretch && (img->gmin == img->gmax))
00344     fill_bytes (block.pixelPtr, img->data[0][0][0], nbytes);
00345   else
00346     {
00347       if (img->nbnd == 3)
00348         {
00349           if (need_stretch)
00350             stretch_rgb (block.pixelPtr, img);
00351           else
00352             transcribe_rgb (block.pixelPtr, img);
00353         }
00354       else
00355         {
00356           if (need_stretch)
00357             stretch_greyscale (block.pixelPtr, img);
00358           else
00359             transcribe_greyscale (block.pixelPtr, img);
00360         }
00361     }
00362 #if (TK_MAJOR_VERSION > 8) || ((TK_MAJOR_VERSION == 8) && (TK_MINOR_VERSION > 3))
00363   Tk_PhotoPutBlock (imageHandle, &block, destX, destY, width, height,
00364                     TK_PHOTO_COMPOSITE_SET);
00365 #else /* (TK_MAJOR_VERSION < 8) || ((TK_MAJOR_VERSION == 8) && (TK_MINOR_VERSION <= 3)) */
00366   Tk_PhotoPutBlock (imageHandle, &block, destX, destY, width, height);
00367 #endif
00368   return TCL_OK;
00369 }
00370 
00375 
00383 static void
00384 write_rgb_SADIE (IMAGE *img, Tk_PhotoImageBlock *blockPtr)
00385 {
00386   size_t h, w;
00387   unsigned char *bytePtr;
00388   
00389   bytePtr = blockPtr->pixelPtr + blockPtr->offset[0];
00390   for (h = 0; h < blockPtr->height; h++)
00391     {
00392       for (w = 0; w < blockPtr->width; w++)
00393         {
00394           img->data[0][h][w] = (PIXEL) *(bytePtr++);
00395           img->data[1][h][w] = (PIXEL) *(bytePtr++);
00396           img->data[2][h][w] = (PIXEL) *(bytePtr++);
00397           bytePtr++; /* Skip any alpha channel data. */
00398         }
00399     }   
00400 }
00401 
00409 static void
00410 write_greyscale_SADIE (IMAGE *img, Tk_PhotoImageBlock *blockPtr)
00411 {
00412   size_t h, w;
00413   unsigned char *bytePtr;
00414   
00415   bytePtr = blockPtr->pixelPtr + blockPtr->offset[0];
00416   for (h = 0; h < blockPtr->height; h++)
00417     {
00418       for (w = 0; w < blockPtr->width; w++)
00419           img->data[0][h][w] = (PIXEL) *(bytePtr++);
00420     }   
00421 }
00437 static int
00438 WriteSADIE (Tcl_Interp *interp, const char *fileName,
00439             Tcl_Obj *format, Tk_PhotoImageBlock *blockPtr)
00440 {
00441   char msg[SLEN];
00442   int greenOffset, blueOffset;
00443   Tcl_Obj *objPtr = NULL;
00444   IMAGE *img = NULL;
00445     
00446   greenOffset = blockPtr->offset[1] - blockPtr->offset[0];
00447   blueOffset = blockPtr->offset[2] - blockPtr->offset[0];
00448   if ((greenOffset == 1) && (blueOffset == 2) && (blockPtr->pixelSize == 4)
00449       && (blockPtr->pitch == (blockPtr->width * 4)))
00450     {
00451       GETMEM (3, blockPtr->height, blockPtr->width, &img);
00452       if (img == NULL)
00453         return TCL_ERROR;
00454       write_rgb_SADIE (img, blockPtr);
00455     }
00456   else if (blockPtr->pixelSize == 1)
00457     {
00458       GETMEM (1, blockPtr->height, blockPtr->width, &img);
00459       if (img == NULL)
00460         return TCL_ERROR;
00461       write_greyscale_SADIE (img, blockPtr);
00462     }
00463   else
00464     {
00465       return TCL_ERROR;
00466     }
00467   if (NAMES)
00468     {
00469       MESSAGE('I', "");
00470       MESSAGE('I', "TKIMGSADIE");
00471       MESSAGE('I', "");
00472       snprintf(msg, SLEN - 1,
00473                " Input file:                                 %s", fileName);
00474       MESSAGE('I', msg); 
00475       snprintf(msg, SLEN - 1,
00476                " Number of bands, lines, pixels:             %lu, %lu, %lu",
00477                (unsigned long) img->nbnd,
00478                (unsigned long) img->nlin,
00479                (unsigned long) img->npix);
00480       MESSAGE('I', msg);
00481       snprintf(msg, SLEN - 1,
00482                " Number of bits/pixel/band:                  %d", 8);
00483       MESSAGE('I', msg);
00484       snprintf(msg, SLEN - 1,
00485                " Graylevel minimum, maximum:                 %10.4e, %10.4e",
00486                img->gmin, img->gmax);
00487       MESSAGE('I', msg);
00488       MESSAGE('I', " ...............");
00489     }
00490   strncpy (img->text, fileName, TLEN - 1);      
00491   objPtr = NewSadieImageObj (img);
00492   if (objPtr != NULL)
00493     Tcl_SetObjResult (interp, objPtr);
00494   return TCL_OK;
00495 }
00496 
00503 int
00504 Sadie_Image_Init (Tcl_Interp *interp)
00505 {
00506   Tk_CreatePhotoImageFormat (&tkImgFmtSADIE);
00507   return TCL_OK;
00508 }

Generated on Fri Jul 8 14:55:01 2005 for tclSadie by  doxygen 1.4.2