home *** CD-ROM | disk | FTP | other *** search
/ Magazyn Amiga 12 / MA_Cover_12.iso / devs / ics / software / ics.lzh / ICS / Programmer / Example2.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-02-22  |  11.9 KB  |  285 lines

  1. /**********************************************************/
  2. /* Copyright   ©1999 Wolf-Juergen Faust                   */
  3. /* Am Dorfgarten 10                                       */
  4. /* 60435 Frankfurt      EXAMPLE2.c                        */
  5. /* Germany                                                */
  6. /* Tel/Fax: +(49) 69 5486556                              */
  7. /*                                                        */
  8. /*                                                        */
  9. /* This piece of source code is part of the current       */
  10. /* ICSConvert version and shows how to call ICS.          */
  11. /* See the included comments and ICS.doc for more         */
  12. /* info when adding ICS support to your software          */
  13. /*                                                        */
  14. /* Unlike Example.c this file corrects multiple pixels    */
  15. /* with a single call to TranslateColors().               */
  16. /*                                                        */
  17. /**********************************************************/
  18.  
  19. #include    <proto/ics.h>
  20.  
  21. struct Library *ICSBase=NULL;
  22.  
  23. /*** VARS ***/
  24.  
  25. UWORD LoadPic(struct Window *, UBYTE *inputfile, UBYTE *outputfile, BOOL nosetup, BOOL nostatus, BOOL nocolor, PSTR prefsfile);
  26. UWORD LoadPic(struct Window *win2, UBYTE *inputfile, UBYTE *outputfile, BOOL nosetup, BOOL nostatus, BOOL nocolor, PSTR prefsfile)
  27. #endif
  28.  
  29. /*** MAIN ***/
  30. {
  31.     UWORD ret = 1;
  32.  
  33.     UWORD wi;
  34.     ULONG x,y, li;
  35.     ULONG size;
  36.     struct IFFHandle *iffhandle;
  37.     UBYTE *temp;
  38.     static void *idc=NULL;
  39.     static void *idctrans=NULL;
  40.     UBYTE *r,*g,*b;
  41.     LONG ifferr;
  42.     struct MyHandle *ilbm;
  43.     struct URGBCOLOR *rgb;
  44.     struct UGRAYCOLOR *gray;
  45.     void *linebuffer;
  46.     COLORTYPE savemode;
  47.  
  48.     if(!inputfile) // signal we want to free all allocated handles?
  49.     {
  50.         if(idctrans)
  51.         {
  52.             DeleteIDCTransform(idctrans);
  53.             idctrans = NULL;
  54.         }
  55.         if(idc)
  56.         {
  57.             DeleteIDC(idc);
  58.             idc = NULL;
  59.         }
  60.         return(0);
  61.     }
  62.     if(!idc) // create a device context if not already present (idc is 
  63.     {
  64.         if(!(idc = CreateIDC(                // create ICS device context object
  65.             ICS_APPNAME, PRGMNAME,           // name of this application
  66.             ICS_APPNAMEVERSION, NUMVERSION,  // version of this application
  67.             ICS_APPICSVERSION, 2,            // version of ICS library this application was made for/with
  68.             ICS_PREFSFILE, prefsfile,
  69.             TAG_DONE)))
  70.         {
  71.             ErrMes(win2, MSG_ICSERR_NOCONTEXT); // Error: Can't create device context using ics.library\n      Maybe not enough memory?
  72.             return(0);
  73.         }
  74.     }
  75.     if(!nosetup) // Does calling function want a setup?
  76.     {
  77.         if(idctrans) // delete any old transformation before new setup.
  78.         {
  79.             DeleteIDCTransform(idctrans);
  80.             idctrans = NULL;
  81.         }
  82.         if(SetupIDCColorMatching(idc, dscreen, TAG_DONE)<=1)  // display ICS preference window. Note: ICSConvert currently does not offer any GUI. So I abort if the user selects cancel...   - returns 0=err, 1=user cancel
  83.         {
  84.             temp = ICSFault(idc, MyGetString(MSG_ICSERR_MSGHEADER)); // Error while running ICSConvert.
  85.             if(!temp) temp = MyGetString(MSG_ICSERR_NOPREFS); // "Error: Can't open ICS preferences.";
  86.             if(ICSErr(idc)>ICS_ERRMSGLIMIT) Mes(temp, win2);
  87.             return(0);
  88.         }
  89.     }
  90.     if(idctrans) ICSStatusWin(idctrans, ICS_StatusText,  MyGetString(MSG_ICSSTATUS_OPENSRCFILE), TAG_DONE);  // change title and text of status window created by ICS library during CreateIDCTransform(): "Opening image file..."
  91.     sprintf(tempstr, PRGMNAME": %s", FilePart(inputfile)); // Generate window title of ICS status window
  92.     if(strlen(tempstr) > 35) sprintf(tempstr, "ICS: %s", FilePart(inputfile));
  93.     if(strlen(tempstr) > 35) stccpy(tempstr, MyGetString(MSG_ICSSTATUS_TITLE), 35);
  94.     if(!idctrans) // Is there a transformation function available from a previous call - if not, make one now
  95.     {
  96.         if(!(idctrans = CreateIDCTransform(idc,
  97.             ICS_TransferDevices, ICS_INPUT_DEVICE,        // We want to convert from input to display device (not printer device)
  98.             ((nostatus) ? TAG_DONE: ICS_StatusOpen), dscreen,                      // Screen to use for status window or NULL for default public screen
  99.             ICS_StatusTitle, tempstr, //  Overwrite status window title with our own: "ICS Image Conversion"
  100.             //ICS_StatusActivate, TRUE,                     // Activate status window
  101.             ICS_StatusKeep, TRUE,                         // keep status window open as we use the ics status window during conversion of image data later
  102.             // ICS_StatusDisableAbort, TRUE,                 // use this to disable Abort/Stop button
  103.             TAG_DONE))) // create input (scanner) to device (display/monitor) color corretion and show status window while processing.. leave status window open for user below...
  104.         {
  105.             temp = ICSFault(idc, MyGetString(MSG_ICSERR_MSGHEADER)); // Error while running ICSConvert.
  106.             if(!temp) temp = MyGetString(MSG_ICSERR_CREATETRANSFORM); // Error: Can't create color transformation using ics.library.
  107.             if(ICSErr(idc)>ICS_ERRMSGLIMIT) Mes(temp, win2);
  108.             return(0);
  109.         }
  110.     } else
  111.     {
  112.         ICSStatusWin(idctrans, ICS_StatusTitle, tempstr, ICS_StatusText,  MyGetString(MSG_ICSSTATUS_OPENSRCFILE), TAG_DONE);  // change status window for new file
  113.     }
  114.     if(ret)
  115.     {
  116.         if(ICSStatusWin(idctrans, ICS_StatusCheck,  0, TAG_DONE))
  117.         {
  118.             ret = 0;
  119.         }
  120.     }
  121.     if(ilbm = (struct MyHandle *) AllocVec(sizeof(struct MyHandle), MEMF_PUBLIC|MEMF_CLEAR))
  122.     {
  123.         stccpy(ilbm->prtfile, inputfile, PATH);
  124.         stccpy(ilbm->savefile, outputfile, PATH);
  125.  
  126.         if(insema = (struct SignalSemaphore *) AllocVec(sizeof(struct SignalSemaphore),MEMF_PUBLIC|MEMF_CLEAR)) // Semaphore used by the image reading routine GetMain()
  127.         {
  128.             InitSemaphore(insema);
  129.  
  130.             if(ret)
  131.             {
  132.                 ilbm->memory = 2;    // Reading routine may use more memory...
  133.                 ilbm->landscape=0;   // No landscape rotation wanted of input
  134.                 if (GetMain(ilbm, POPEN, win2, 0))  // open source image file for conversion
  135.                 {
  136.                     ilbm->savemode = ilbm->destmode; // set var indicating the output file type: 1=gray 0=color depending on input ("destmode" is the input file mode),
  137.                     if(nocolor) ilbm->savemode = 1;  // user asked for grayscale only output?
  138.                     if (GetMain(ilbm, PREADINIT, win2, 0))  // init read routines for file
  139.                     {
  140.                         size = ilbm->wssize * ( (ilbm->destmode)  ? sizeof(struct UGRAYCOLOR) : sizeof(struct URGBCOLOR) );
  141.                         if(linebuffer = AllocVec(size, MEMF_CLEAR))
  142.                         {
  143.                             ICSStatusWin(idctrans, ICS_StatusText,  MyGetString(MSG_ICSSTATUS_OPENDESTFILE), TAG_DONE);  // "Opening destination file"
  144.                             if(iffhandle = OPENMYFILE(ilbm, win2)) // open destination image file for color corrected image
  145.                             {
  146.                                 if(ifferr = PushChunk(iffhandle,ID_ILBM,ID_BODY,IFFSIZE_UNKNOWN)) // Start writing the main body of destination image file
  147.                                 {
  148.                                     ErrMes(win2, MSG_IFFERR_WRITECHUNK, ifferr, "BODY", ( (strlen(ilbm->savefile)>60) ? FilePart(ilbm->savefile) : ilbm->savefile )); // Error (Type %ld): Can't write '%s' chunk of\ndestination file: '%s'.
  149.                                     ret = 0;
  150.                                 } else
  151.                                 {
  152.                                     if (SetSignal(0,0) & SIGBREAKF_CTRL_C) ret=0; // check if user aborted ICSConvert...
  153.                                     for(ret=1,y=0; (ret) && (y<ilbm->hssize); y++)  // loop for number of lines in image
  154.                                     {
  155.                                         // Display progress status and check for user abort...
  156.                                         sprintf(tempstr, MyGetString(MSG_ICSSTATUS_COMPLETE), (y*100)/ilbm->hssize); // Converting Image  -  %ld%% complete
  157.                                          // change status text and update progress bar. Also check if user wants to abort...
  158.                                         if(ICSStatusWin(idctrans, ICS_StatusText,  tempstr, ICS_StatusProgress, (y*100)/ilbm->hssize, ICS_StatusCheck,  0, TAG_DONE))
  159.                                         {
  160.                                             ret = 0;
  161.                                             break;
  162.                                         }
  163.                                         // read a single image line into buffer.
  164.                                         if(temp = (UBYTE *)GetMain(ilbm, PREADLINE, win2, y))
  165.                                         {
  166.                                             if(ilbm->destmode) // is source a grayscale image?  Note: white=255  gray=0
  167.                                             {
  168.                                                 for(x=0, gray=linebuffer; (ret) && (x<ilbm->wssize); x++, gray++)  // loop for number of pixels in line
  169.                                                 {
  170.                                                     gray->gray = (temp[x]<<8) | temp[x];  // convert 8 bit to 16 bit unsigned graylevel. IMPORTANT: Black=0   White=65535
  171.                                                 }
  172.                                                 if(!(TranslateColors(idctrans, linebuffer, ilbm->wssize, COLOR_UGRAY, linebuffer, COLOR_UGRAY)))
  173.                                                 {
  174.                                                     temp = ICSFault(idc, MyGetString(MSG_ICSERR_CONVERT)); // Error while converting color using ICS.
  175.                                                     if(!temp) temp = MyGetString(MSG_ICSERR_CONVERT);
  176.                                                     if(ICSErr(idc)>ICS_ERRMSGLIMIT) Mes(temp, win2);
  177.                                                     ret = 0;
  178.                                                     break;
  179.                                                 }
  180.                                                 r = temp;
  181.                                                 for(x=0, gray=linebuffer; (ret) && (x<ilbm->wssize); x++, gray++)  // loop for number of pixels in line
  182.                                                 {
  183.                                                     *r++ = gray->gray >> 8;
  184.                                                 }
  185.                                             } else
  186.                                             {
  187.                                                 r = temp;
  188.                                                 g = r + ilbm->wssize;
  189.                                                 b = g + ilbm->wssize;
  190.     
  191.                                                 for(x=0, rgb=linebuffer; (ret) && (x<ilbm->wssize); x++, rgb++)  // loop for number of pixels in line
  192.                                                 {
  193.                                                     rgb->red   = (r[x]<<8) | r[x];  // convert 8 bit to 16 bit unsigned RGB color
  194.                                                     rgb->green = (g[x]<<8) | g[x];
  195.                                                     rgb->blue  = (b[x]<<8) | b[x];
  196.                                                 }
  197.                                                 savemode = ((ilbm->savemode) ? COLOR_UGRAY : COLOR_URGB); // note: linebuffer is used as input and output but input maybe URGB while output is UGRAY. This only works because UGRAY is smaller than URGB.
  198.                                                 if(!(TranslateColors(idctrans, linebuffer, ilbm->wssize, COLOR_URGB, linebuffer, savemode)))
  199.                                                 {
  200.                                                     temp = ICSFault(idc, MyGetString(MSG_ICSERR_CONVERT)); // Error while converting color using ICS.
  201.                                                     if(!temp) temp = MyGetString(MSG_ICSERR_CONVERT);
  202.                                                     if(ICSErr(idc)>ICS_ERRMSGLIMIT) Mes(temp, win2);
  203.                                                     ret = 0;
  204.                                                     break;
  205.                                                 }
  206.                                                 if(ilbm->savemode) // is the output gray or color?
  207.                                                 {
  208.                                                     r = temp;
  209.                                                     for(x=0, gray=linebuffer; (ret) && (x<ilbm->wssize); x++, gray++)  // loop for number of pixels in line
  210.                                                     {
  211.                                                         *r++ = gray->gray >> 8;
  212.                                                     }
  213.                                                 } else
  214.                                                 {
  215.                                                     r = temp;
  216.                                                     g = r + ilbm->wssize;
  217.                                                     b = g + ilbm->wssize;
  218.                                                     for(x=0, rgb=linebuffer; (ret) && (x<ilbm->wssize); x++, rgb++)  // loop for number of pixels in line
  219.                                                     {
  220.                                                         *r++ = rgb->red >> 8;
  221.                                                         *g++ = rgb->green >> 8;
  222.                                                         *b++ = rgb->blue >> 8;
  223.                                                         //KPrintF("x %ld  %ld %ld %ld\n",r[x],g[x],b[x]);
  224.                                                     }
  225.                                                 }
  226.                                             }
  227.                                             if(!(WRITEMYLINE(ilbm, win2, iffhandle, temp)))
  228.                                             {
  229.                                                 ret = 0;
  230.                                                 break;
  231.                                             }
  232.                                         } else
  233.                                         {
  234.                                             ret = 0;
  235.                                             break;
  236.                                         }
  237.                                         if (SetSignal(0,0) & SIGBREAKF_CTRL_C) ret=0;
  238.                                     }
  239.                                     if(ret)
  240.                                     {
  241.                                         if(ifferr = PopChunk(iffhandle))
  242.                                         {
  243.                                             ErrMes(win2, MSG_IFFERR_WRITECHUNK, ifferr, "BODY", ( (strlen(ilbm->savefile)>60) ? FilePart(ilbm->savefile) : ilbm->savefile )); // Error (Type %ld): Can't write '%s' chunk of\ndestination file: '%s'.
  244.                                             ret = 0;
  245.                                         }
  246.                                     }
  247.                                 }
  248.                                 ICSStatusWin(idctrans, ICS_StatusText,  MyGetString(MSG_ICSSTATUS_CLOSING), TAG_DONE);  // Closing source and destination file
  249.                                 CLOSEMYFILE(iffhandle);
  250.                                 if( (!ret) && (iffhandle) ) // Delete written file after error
  251.                                 {
  252.                                     DeleteFile(ilbm->savefile);
  253.                                 }
  254.                             }
  255.                             FreeVec(linebuffer);
  256.                         } else
  257.                         {
  258.                             ErrMes(NULL, MSG_ERR_MEMORY, size); // Not enough free memory.\nFailed to get %ld bytes.
  259.                         }
  260.                         GetMain(ilbm, PREADEND, win2, 0);
  261.                     } else
  262.                     {
  263.                         ret = 0;
  264.                     }
  265.                     GetMain(ilbm, PCLOSE, win2, 0);
  266.                     ICSStatusWin(idctrans, ICS_StatusText,  MyGetString(MSG_ICSSTATUS_FINISH), TAG_DONE);  // Finished processing of file
  267.                 } else
  268.                 {
  269.                     ret = 0;
  270.                 }
  271.             }
  272.             FreeVec(insema);
  273.         } else
  274.         {
  275.             ErrMes(win2, MSG_ERR_MEMORY, sizeof(struct SignalSemaphore)); // Not enough free memory.\nFailed to get %ld bytes.
  276.             ret = 0;
  277.         }
  278.         FreeVec(ilbm);
  279.     } else
  280.     {
  281.         ErrMes(NULL, MSG_ERR_MEMORY, sizeof(struct MyHandle)); // Not enough free memory.\nFailed to get %ld bytes.
  282.     }
  283.     return(ret);
  284. }
  285.