Main Page   Data Structures   File List   Data Fields   Globals  

Sadie_Image.c

Go to the documentation of this file.
00001 /*-Copyright Information------------------------------------------------------*/
00002 /* Copyright (c) 1988 by the University of Arizona Digital Image Analysis Lab */
00003 /*-General Information--------------------------------------------------------*/
00004 /*                                                                            */
00005 
00006 /*   This function reads a SADIE image from disk into main memory.  A photo   */
00007 /*   image  string  handler for  SADIE  image  strings.   This function  is   */
00008 /*   modeled after  the file tkImgPPM.c  which is contained in  the generic   */
00009 /*   directory of the Tk source distribution.                                 */
00010 /*                                                                            */
00011 
00012 /*   Rather than taking  an image file name or pixel  data string as input,   */
00013 /*   the memory address of a SADIE image that is already loaded into memory   */
00014 /*   is passed  in through the string  interface. This is  using the string   */
00015 /*   interface  in a  way other  than it  was intended,  but it  provides a   */
00016 /*   convenient interface none the less.                                      */
00017 /*                                                                            */
00018 /*----------------------------------------------------------------------------*/
00019 
00020 #define  USE_OLD_IMAGE
00021 
00022 #include <tcl.h>
00023 #include <tk.h>
00024 #include <string.h>
00025 #include "sadie.h"
00026 
00027 /* The format record for the SADIE string format: */
00028 static int MatchSADIE _ANSI_ARGS_ ((char *string,
00029                                     char *formatString,
00030                                     int *widthPtr, int *heightPtr));
00031 
00032 static int ReadSADIE _ANSI_ARGS_ ((Tcl_Interp * interp,
00033                                    char *string,
00034                                    char *formatString,
00035                                    Tk_PhotoHandle imageHandle,
00036                                    int destX, int destY,
00037                                    int width, int height,
00038                                    int srcX, int srcY));
00039 
00040 static int WriteSADIE _ANSI_ARGS_ ((Tcl_Interp * interp,
00041                                     char *ImgName,
00042                                     char *formatString,
00043                                     Tk_PhotoImageBlock * blockPtr));
00044 
00045 Tk_PhotoImageFormat tkImgFmtSADIE = {
00046   "SADIE",                      /* Name of the image format */
00047   NULL,                         /* File match procedure     */
00048   MatchSADIE,                   /* String match procedure   */
00049   NULL,                         /* File read procedure      */
00050   ReadSADIE,                    /* String read procedure    */
00051   WriteSADIE,                   /* File write procedure     */
00052   NULL,                         /* String write procedure   */
00053 };
00054 
00055 /*-Copyright Information------------------------------------------------------*/
00056 /* Copyright (c) 1988 by the University of Arizona Digital Image Analysis Lab */
00057 /*-General Information--------------------------------------------------------*/
00058 /* MatchSADIE -                                                               */
00059 /*                                                                            */
00060 /*   This procedure is  invoked by the photo image type  to see if image      */
00061 /*   data is in SADIE format.                                                 */
00062 /*                                                                            */
00063 /* Results:                                                                   */
00064 /*   The return value  is >0 if the first  characters in string "string"      */
00065 /*   look like SADIE data, and 0 otherwise.                                   */
00066 /*                                                                            */
00067 /* Side effects:                                                              */
00068 /*   The access position in file may change.                                  */
00069 /*                                                                            */
00070 /*----------------------------------------------------------------------------*/
00071 /*-Interface Information------------------------------------------------------*/
00072 static int
00073 MatchSADIE (char *string,       /*  I   The string, open for reading.                 */
00074             char *formatString, /*  I   User-specified format string, or NULL.        */
00075             int *widthPtr,      /*  O   The dimensions of the image are returned here */
00076             int *heightPtr      /*  O   if the string is a valid raw SADIE string.    */
00077 /*----------------------------------------------------------------------------*/
00078   )
00079 {
00080   int imgaddr;
00081   IMAGE *img;
00082 
00083   sscanf (string, "%x", &imgaddr);
00084   img = (IMAGE *) imgaddr;
00085 
00086   if (CHECKIMG (img))
00087     {
00088       *widthPtr = img->npix;
00089       *heightPtr = img->nlin;
00090       return (1);
00091     }
00092   else
00093     return (0);
00094 }
00095 
00096 /*-Copyright Information------------------------------------------------------*/
00097 /* Copyright (c) 1988 by the University of Arizona Digital Image Analysis Lab */
00098 /*-General Information--------------------------------------------------------*/
00099 /* ReadSADIE -                                                               */
00100 /*                                                                            */
00101 /*   This procedure is called by the  photo image type to read SADIE format   */
00102 /*   data from a string and write it into a given photo image.                */
00103 /*                                                                            */
00104 /* Results:                                                                   */
00105 /*   A standard TCL completion code. If TCL_ERROR is returned then an error   */
00106 /*   message is left in interp->result.                                       */
00107 /*                                                                            */
00108 /* Side effects:                                                              */
00109 /*   The access  position in  string "string" is  changed, and new  data is   */
00110 /*   added to the image given by imageHandle.                                 */
00111 /*                                                                            */
00112 /*----------------------------------------------------------------------------*/
00113 /*-Interface Information------------------------------------------------------*/
00114 static int
00115 ReadSADIE (Tcl_Interp * interp, /*  I   Interpreter to use for reporting errors.  */
00116            char *string,        /*  I   The image string, open for reading.       */
00117            char *formatString,  /*  I   User-specified format string, or NULL.    */
00118            Tk_PhotoHandle imageHandle,  /*  I   The photo image to write into.            */
00119            int destX,           /*  I   Coordinates of top-left pixel in          */
00120            int destY,           /*         photo image to be written to.          */
00121            int width,           /*  I   Dimensions of block of photo image to     */
00122            int height,          /*         be written to.                         */
00123            int srcX,            /*  I   Coordinates of top-left pixel to be used  */
00124            int srcY             /*         in image being read.                   */
00125 /*----------------------------------------------------------------------------*/
00126   )
00127 {
00128   int nLines, nBytes, h, type, count;
00129   unsigned char *pixelPtr;
00130   int j, k;
00131   int stretchmin = DMIN;        /* Linear stretch minimum value, used for displayed image */
00132   int stretchmax = DMAX;        /* Linear stretch maximum value, used for displayed image */
00133   int stretchMin = 0;
00134   int stretchMax = 255;
00135   double offset, factor;
00136   int imgaddr;
00137   int option;
00138   int var_exists;
00139   Tk_PhotoImageBlock block;
00140   IMAGE *img;
00141   BYTE pixel;
00142 
00143   Tcl_Eval (interp, "info exists SadieVar(getstretched)");
00144   Tcl_GetIntFromObj (interp, Tcl_GetObjResult (interp), &var_exists);
00145   if (var_exists)
00146     {
00147       Tcl_GetInt (interp,
00148                   Tcl_GetVar2 (interp, "SadieVar", "getstretched",
00149                                TCL_GLOBAL_ONLY), &option);
00150     }
00151   else
00152     {
00153       option = 1;
00154     }
00155 
00156   sscanf (string, "%x", &imgaddr);
00157   img = (IMAGE *) imgaddr;
00158 
00159   if (!CHECKIMG (img))
00160     {
00161       Tcl_AppendResult (interp,
00162                         "Couldn't identify SADIE image from input string.",
00163                         NULL);
00164       return TCL_ERROR;
00165     }
00166   if ((img->nbnd < 1))
00167     {
00168       Tcl_AppendResult (interp, "Image bands not within display range.",
00169                         NULL);
00170       return TCL_ERROR;
00171     }
00172   if (img->nlin <= 0)
00173     {
00174       Tcl_AppendResult (interp, "Image lines not within display range.",
00175                         NULL);
00176       return TCL_ERROR;
00177     }
00178   if (img->npix <= 0)
00179     {
00180       Tcl_AppendResult (interp, "Image pixels not within display range.",
00181                         NULL);
00182       return TCL_ERROR;
00183     }
00184 
00185   if (width > img->npix)
00186     {
00187       width = img->npix;
00188     }
00189   if (height > img->nlin)
00190     {
00191       height = img->nlin;
00192     }
00193   if ((width <= 0) || (height <= 0))
00194     {
00195       return TCL_OK;
00196     }
00197 
00198   if (img->nbnd != 3)
00199     {                           /* Grayscale image */
00200       block.pixelSize = 1;
00201       block.offset[0] = 0;
00202       block.offset[1] = 0;
00203       block.offset[2] = 0;
00204     }
00205   else
00206     {                           /* RGB image */
00207       block.pixelSize = 3;
00208       block.offset[0] = 0;
00209       block.offset[1] = 1;
00210       block.offset[2] = 2;
00211     }
00212 
00213   block.width = width;
00214   block.pitch = block.pixelSize * img->npix;
00215 
00216   Tk_PhotoExpand (imageHandle, destX + width, destY + height);
00217 
00218   nLines = height;
00219   if (nLines <= 0)
00220     {
00221       nLines = 1;
00222     }
00223 
00224   nBytes = nLines * block.pitch;
00225 
00226   pixelPtr = (unsigned char *) ckalloc ((unsigned) nBytes);
00227   block.pixelPtr = pixelPtr;
00228 
00229   RANGE (img);
00230 
00231   if (block.pixelSize == 1)
00232     {
00233       if (option == 1)
00234         {                       /* Stretch the image */
00235 
00236           if ((PIXEL) stretchMin == img->gmin
00237               && img->gmax == (PIXEL) stretchMax)
00238             {
00239               for (j = 0; j < img->nlin; j++)
00240                 {
00241                   for (k = 0; k < img->npix; k++)
00242                     {
00243                       pixel = (BYTE) img->data[0][j][k];
00244                       *pixelPtr++ = pixel;
00245                     }
00246                 }
00247             }
00248           else if (img->gmin < img->gmax)
00249             {
00250               factor =
00251                 (double) (stretchMax - stretchMin) / (double) (img->gmax -
00252                                                                img->gmin);
00253               offset = (double) (stretchMin) - (double) (img->gmin) * factor;
00254 
00255               for (j = 0; j < img->nlin; j++)
00256                 {
00257                   for (k = 0; k < img->npix; k++)
00258                     {
00259                       pixel =
00260                         (BYTE) ((double) (img->data[0][j][k]) * factor +
00261                                 offset);
00262                       *pixelPtr++ = pixel;
00263                     }
00264                 }
00265             }
00266           else
00267             {                   /* (img->gmin == img->gmax) */
00268               factor =
00269                 (double) (stretchMax - stretchMin) / (double) (SMAX - SMIN);
00270               pixel =
00271                 (BYTE) ((double)
00272                         (min (max (SMIN, img->data[0][0][0]), SMAX) -
00273                          SMIN) * factor + (double) stretchMin);
00274 
00275               for (j = 0; j < img->nlin; j++)
00276                 {
00277                   for (k = 0; k < img->npix; k++)
00278                     {
00279                       *pixelPtr++ = pixel;
00280                     }
00281                 }
00282             }
00283         }
00284       else
00285         {                       /* Don't stretch the image */
00286 
00287           for (j = 0; j < img->nlin; j++)
00288             {
00289               for (k = 0; k < img->npix; k++)
00290                 {
00291                   pixel = (BYTE) img->data[0][j][k];
00292                   *pixelPtr++ = pixel;
00293                 }
00294             }
00295         }
00296 
00297       block.height = height;
00298       Tk_PhotoPutBlock (imageHandle, &block, destX, destY, width, height);
00299 
00300     }
00301   else if (block.pixelSize == 3)
00302     {
00303       if (option == 1)
00304         {                       /* Stretch the image */
00305 
00306           if ((PIXEL) stretchMin == img->gmin
00307               && img->gmax == (PIXEL) stretchMax)
00308             {
00309               for (j = 0; j < img->nlin; j++)
00310                 {
00311                   for (k = 0; k < img->npix; k++)
00312                     {
00313                       pixel = (BYTE) img->data[0][j][k];
00314                       *pixelPtr++ = pixel;
00315                       pixel = (BYTE) img->data[1][j][k];
00316                       *pixelPtr++ = pixel;
00317                       pixel = (BYTE) img->data[2][j][k];
00318                       *pixelPtr++ = pixel;
00319                     }
00320                 }
00321             }
00322           else if (img->gmin < img->gmax)
00323             {
00324               factor =
00325                 (double) (stretchMax - stretchMin) / (double) (img->gmax -
00326                                                                img->gmin);
00327               offset = (double) (stretchMin) - (double) (img->gmin) * factor;
00328 
00329               for (j = 0; j < img->nlin; j++)
00330                 {
00331                   for (k = 0; k < img->npix; k++)
00332                     {
00333                       pixel =
00334                         (BYTE) ((double) (img->data[0][j][k]) * factor +
00335                                 offset);
00336                       *pixelPtr++ = pixel;
00337                       pixel =
00338                         (BYTE) ((double) (img->data[1][j][k]) * factor +
00339                                 offset);
00340                       *pixelPtr++ = pixel;
00341                       pixel =
00342                         (BYTE) ((double) (img->data[2][j][k]) * factor +
00343                                 offset);
00344                       *pixelPtr++ = pixel;
00345                     }
00346                 }
00347             }
00348           else
00349             {                   /* (img->gmin == img->gmax) */
00350 
00351               factor =
00352                 (double) (stretchMax - stretchMin) / (double) (SMAX - SMIN);
00353               pixel =
00354                 (BYTE) ((double)
00355                         (min (max (SMIN, img->data[0][0][0]), SMAX) -
00356                          SMIN) * factor + (double) stretchMin);
00357 
00358               for (j = 0; j < img->nlin; j++)
00359                 {
00360                   for (k = 0; k < img->npix; k++)
00361                     {
00362                       *pixelPtr++ = pixel;
00363                       *pixelPtr++ = pixel;
00364                       *pixelPtr++ = pixel;
00365                     }
00366                 }
00367             }
00368         }
00369       else
00370         {                       /* Don't stretch the image */
00371 
00372           for (j = 0; j < img->nlin; j++)
00373             {
00374               for (k = 0; k < img->npix; k++)
00375                 {
00376                   pixel = (BYTE) img->data[0][j][k];
00377                   *pixelPtr++ = pixel;
00378                   pixel = (BYTE) img->data[1][j][k];
00379                   *pixelPtr++ = pixel;
00380                   pixel = (BYTE) img->data[2][j][k];
00381                   *pixelPtr++ = pixel;
00382                 }
00383             }
00384         }
00385 
00386       block.height = height;
00387       Tk_PhotoPutBlock (imageHandle, &block, destX, destY, width, height);
00388 
00389     }
00390   else
00391     printf ("tkImgSADIE does not support a pixel size of: %d \n",
00392             block.pixelSize);
00393 
00394   return TCL_OK;
00395 }
00396 
00397 /*-Copyright Information------------------------------------------------------*/
00398 /* Copyright (c) 1988 by the University of Arizona Digital Image Analysis Lab */
00399 /*-General Information--------------------------------------------------------*/
00400 /* WriteSADIE -                                                               */
00401 /*                                                                            */
00402 /*   This procedure  is called  by the  photo image type  to write  a photo   */
00403 /*   image to a SADIE image.                                                  */
00404 /*                                                                            */
00405 /* Results:                                                                   */
00406 /*   A  standard TCL  completion code.   If TCL_ERROR  is returned  then an   */
00407 /*   error message is left in interp->result.                                 */
00408 /*                                                                            */
00409 /*----------------------------------------------------------------------------*/
00410 /*-Interface Information------------------------------------------------------*/
00411 static int
00412 WriteSADIE (Tcl_Interp * interp,        /*  I   Interpreter to use for reporting errors. */
00413             char *ImgName,      /*  I   The address of image to write to.        */
00414             char *formatString, /*  I   User-specified format string, or NULL.   */
00415             Tk_PhotoImageBlock * blockPtr       /*  I   pointer to photo image data.             */
00416   )
00417 {
00418   char msg[SLEN];
00419   unsigned char *pixelPtr, *pixLinePtr;
00420   int w, h;
00421   int greenOffset, blueOffset, nBytes;
00422   int addrstr;
00423   int pixint;
00424   IMAGE *img;
00425   PIXEL pixflt;
00426 
00427   /* create image of appropriate size */
00428   if (!CHECKIMG (img))
00429     GETMEM (3, blockPtr->height, blockPtr->width, &img);
00430   if (!img)
00431     return TCL_ERROR;
00432 
00433   pixLinePtr = blockPtr->pixelPtr + blockPtr->offset[0];
00434   greenOffset = blockPtr->offset[1] - blockPtr->offset[0];
00435   blueOffset = blockPtr->offset[2] - blockPtr->offset[0];
00436 
00437 /*    if ((greenOffset == 1) && (blueOffset == 2) && (blockPtr->pixelSize == 3)
00438         && (blockPtr->pitch == (blockPtr->width * 3))) { */
00439   if (greenOffset == 1 && blueOffset == 2 && blockPtr->pixelSize == 4
00440       && blockPtr->pitch == (blockPtr->width * 4))
00441     {
00442       pixelPtr = pixLinePtr;
00443 
00444       for (h = 0; h < blockPtr->height; h++)
00445         {
00446           for (w = 0; w < blockPtr->width; w++)
00447             {
00448               pixint = *pixelPtr;
00449               pixflt = (PIXEL) pixint;
00450               img->data[0][h][w] = pixflt;
00451 
00452               pixelPtr++;
00453               pixint = *pixelPtr;
00454               pixflt = (PIXEL) pixint;
00455               img->data[1][h][w] = pixflt;
00456 
00457               pixelPtr++;
00458               pixint = *pixelPtr;
00459               pixflt = (PIXEL) pixint;
00460               img->data[2][h][w] = pixflt;
00461               pixelPtr += 2;
00462             }
00463         }
00464 
00465       if (NAMES)
00466         {
00467           MESSAGE ('I', "");
00468           MESSAGE ('I', "TKIMGSADIE");
00469           MESSAGE ('I', "");
00470           sprintf (msg, " Input file:                                 %s",
00471                    ImgName);
00472           MESSAGE ('I', msg);
00473           sprintf (msg,
00474                    " Number of bands, lines, pixels:             %d, %d, %d",
00475                    img->nbnd, img->nlin, img->npix);
00476           MESSAGE ('I', msg);
00477           sprintf (msg, " Number of bits/pixel/band:                  %d", 8);
00478           MESSAGE ('I', msg);
00479           sprintf (msg,
00480                    " Graylevel minimum, maximum:                 %10.4e, %10.4e",
00481                    img->gmin, img->gmax);
00482           MESSAGE ('I', msg);
00483           MESSAGE ('I', " ...............");
00484         }
00485 
00486       addrstr = (int) img;
00487 
00488       sprintf (img->text, "%s", ImgName);
00489       sprintf (msg, "%x", addrstr);
00490       Tcl_SetResult (interp, msg, TCL_VOLATILE);
00491 
00492       return TCL_OK;
00493     }
00494   else if (blockPtr->pixelSize == 1)
00495     {                           /* If Grayscale image */
00496 
00497       img->nbnd = 1;
00498       img->npix = blockPtr->width;
00499       img->nlin = blockPtr->height;
00500       img->nbit = 32;
00501 
00502       pixelPtr = pixLinePtr;
00503 
00504       for (h = 0; h < blockPtr->height; h++)
00505         {
00506           for (w = 0; w < blockPtr->width; w++)
00507             {
00508               img->data[0][h][w] = (PIXEL) pixelPtr[0];
00509               pixelPtr++;
00510             }
00511         }
00512 
00513       if (NAMES)
00514         {
00515           MESSAGE ('I', "");
00516           MESSAGE ('I', "TKIMGSADIE");
00517           MESSAGE ('I', "");
00518           sprintf (msg, " Input file:                                 %s",
00519                    ImgName);
00520           MESSAGE ('I', msg);
00521           sprintf (msg,
00522                    " Number of bands, lines, pixels:             %d, %d, %d",
00523                    img->nbnd, img->nlin, img->npix);
00524           MESSAGE ('I', msg);
00525           sprintf (msg, " Number of bits/pixel/band:                  %d", 8);
00526           MESSAGE ('I', msg);
00527           sprintf (msg,
00528                    " Graylevel minimum, maximum:                 %10.4e, %10.4e",
00529                    img->gmin, img->gmax);
00530           MESSAGE ('I', msg);
00531           MESSAGE ('I', " ...............");
00532         }
00533 
00534       addrstr = (int) img;
00535 
00536       sprintf (img->text, "%s", ImgName);
00537       sprintf (msg, "%x", addrstr);
00538       Tcl_SetResult (interp, msg, TCL_VOLATILE);
00539 
00540       return TCL_OK;
00541     }
00542   else
00543     return TCL_ERROR;
00544 
00545 }
00546 
00547 int
00548 Sadie_Image_Init (Tcl_Interp * interp)
00549 {
00550 
00551   Tk_CreatePhotoImageFormat (&tkImgFmtSADIE);
00552 
00553   return TCL_OK;
00554 }

Generated on Sun May 18 15:36:16 2003 for tclSadie by doxygen1.3