home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 7 / Apprentice-Release7.iso / Source Code / C / Applications / POV-Ray 3.0.2 / src / MacSource / SaveCmpPict.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-05-24  |  12.8 KB  |  440 lines  |  [TEXT/CWIE]

  1. /*
  2. ==============================================================================
  3. Project:    POV-Ray
  4.  
  5. Version:    3
  6.  
  7. File Name:    SaveCmpPict.c
  8.  
  9. Description:
  10.     Routines for saving a PICT file in QuickTime compressed format.
  11.     
  12.     This source code was written with a lot of help from some examples
  13.     off of Apple's QuickTime 1.0 Developer CD.
  14.  
  15. Related Files:
  16.     SaveCmpPict.h: header file for Save Compressed Pict routines
  17.     SaveCmpPict.c: main file for Save Compressed Pict routines
  18. ------------------------------------------------------------------------------
  19. Author:
  20.     Eduard [esp] Schwan
  21. ------------------------------------------------------------------------------
  22.     from Persistence of Vision(tm) Ray Tracer
  23.     Copyright 1996 Persistence of Vision Team
  24. ------------------------------------------------------------------------------
  25.     NOTICE: This source code file is provided so that users may experiment
  26.     with enhancements to POV-Ray and to port the software to platforms other 
  27.     than those supported by the POV-Ray Team.  There are strict rules under
  28.     which you are permitted to use this file.  The rules are in the file
  29.     named POVLEGAL.DOC which should be distributed with this file. If 
  30.     POVLEGAL.DOC is not available or for more info please contact the POV-Ray
  31.     Team Coordinator by leaving a message in CompuServe's Graphics Developer's
  32.     Forum.  The latest version of POV-Ray may be found there as well.
  33.  
  34.     This program is based on the popular DKB raytracer version 2.12.
  35.     DKBTrace was originally written by David K. Buck.
  36.     DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
  37. ------------------------------------------------------------------------------
  38. Change History:
  39.     920414    [esp]    Created.
  40.     920418    [esp]    Broke routines into UI and non-UI components for later factoring
  41.     920419    [esp]    Embellished file header comments, renamed routines for consistency
  42.     920611    [esp]    Worked on AppendFinderIcons2PictF function
  43.     930526    [esp]    Updated SC dialog & Compression calls for QT 1.5
  44.     931001    [esp]    version 2.0 finished (Released on 10/4/93)
  45. ==============================================================================
  46. */
  47.  
  48.  
  49. /*==== Headers ====*/
  50.  
  51. #include "SaveCmpPict.h"
  52. #include "PovMac.h"        // kRsrcFileClosed
  53. #include "FilePrefs.h"    // gPrefs2Use_h
  54.  
  55. #include <errors.h>        // dupFNErr
  56. #include <finder.h>        // for kCustomIconResource
  57. #include <resources.h>
  58. #include <icons.h>        // for large1BitMask etc.
  59.  
  60.  
  61. /*
  62. ******************************************************************************
  63. Name:
  64.     AppendFilePreview2PictF
  65. ------------------------------------------------------------------------------
  66. Purpose:
  67.     Create a preview image for users of QuickTime™ standard File preview.
  68. ------------------------------------------------------------------------------
  69. Description:
  70.     ** How it does it
  71. ------------------------------------------------------------------------------
  72. Parameters:
  73. ------------------------------------------------------------------------------
  74. When Used:
  75.     ** who calls me and why/when
  76. ******************************************************************************
  77. */
  78. OSErr AppendFilePreview2PictF(FSSpec *fsFile)
  79. {
  80.     OSErr    anError = noErr;
  81.     short    fileResRef;
  82.  
  83.     fileResRef = FSpOpenResFile(fsFile, fsRdWrPerm);
  84.     anError = ResError();
  85.  
  86.     if (!anError && (fileResRef != -1))
  87.     {
  88.         anError = MakeFilePreview(fileResRef, (ICMProgressProcRecordPtr)-1);
  89.         CloseResFile(fileResRef);
  90.     }
  91.     return anError;
  92. } // AppendFilePreview2PictF
  93.  
  94.  
  95. /*
  96. ******************************************************************************
  97. Name:
  98.     AppendFinderIcons2PictF
  99. ------------------------------------------------------------------------------
  100. Purpose:
  101.     Embed custom icons in file, for System 7.0 users to see from the Finder.
  102. ------------------------------------------------------------------------------
  103. Description:
  104.     ** How it does it
  105. ------------------------------------------------------------------------------
  106. Parameters:
  107. ------------------------------------------------------------------------------
  108. When Used:
  109.     ** who calls me and why/when
  110. ******************************************************************************
  111. */
  112. OSErr AppendFinderIcons2PictF(FSSpec *fsFile,
  113.                         Rect *theOriginalPicFrame,
  114.                         eAFI_ImagePrefs_t theImagePrefs)
  115. {    
  116.     OSErr        anError;
  117.     GWorldPtr    iconGWorld = NULL,
  118.                 imageWorld = NULL;
  119.     short        oldResFile;
  120.     Rect        irect,
  121.                 orect,
  122.                 maxRect;
  123.     Handle        tmpHandle;
  124.     Handle        destIconRsrc;
  125.     short        rowBytes,
  126.                 theWidth,
  127.                 theHeight,
  128.                 theDepth,
  129.                 iconCounter;
  130.     SignedByte    mmumode;
  131.     signed char theCorner;
  132.     short        i,j;
  133.     Ptr            srcPixPtr,
  134.                 tempDestPixPtr,
  135.                 tempSrcPixPtr;
  136.     short        bytesPerRow;
  137.     short        theSize;
  138.     OSType        theRsrcType;
  139.     FInfo        finfo;
  140.     short        fileRef;
  141.  
  142.     oldResFile = CurResFile();    // remember old file
  143.  
  144.     // Create a GWorld to hold the 32x32 image from which to copy..
  145.     SetRect(&orect, 0, 0, 32, 32);
  146.     anError = NewGWorld(&imageWorld, 32, &orect, (CTabHandle)NULL, (GDHandle)NULL, (GWorldFlags)0);
  147.  
  148.     if (!anError)
  149.     {
  150.         // clear it
  151.         SetGWorld(imageWorld, (GDHandle)NULL);
  152.         EraseRect(&orect);
  153.         // prepare to calculate copy rectangles
  154.         maxRect = irect = *theOriginalPicFrame;
  155.         theWidth = irect.right - irect.left;
  156.         theHeight = irect.bottom - irect.top;
  157.  
  158.         // Figure out the source rectangle
  159.         switch (theImagePrefs)
  160.         {
  161.         case eAFI_ShrinkWholeImage:
  162.             /* this saves the whole image as the icon */
  163.             irect = orect;    // shrink down to 32x32
  164.             break;
  165.         case eAFI_UseCenter:
  166.             /* Questionable code.. need to scrutinize this! Not that I don't trust MacDTS..*/
  167.             /* this takes a square from the center of the image */
  168.             if (theWidth > theHeight) 
  169.                 maxRect.right = maxRect.left + theHeight;
  170.              else 
  171.                 maxRect.bottom = maxRect.top + theWidth;
  172.             MapRect(&irect, &maxRect, &orect);
  173.             theWidth = 32 - (irect.right - irect.left);
  174.             theHeight = 32 - (irect.bottom - irect.top);
  175.             OffsetRect(&irect, theWidth>>1, theHeight>>1);
  176.             break;
  177.         } // switch
  178.     }
  179.  
  180.     // Draw the image into the GWorld, open data fork of file, and draw image from file
  181.     if (!anError)
  182.         anError = FSpOpenDF(fsFile, fsRdPerm, &fileRef);
  183.     if (!anError)
  184.     {
  185.         anError = DrawPictureFile(fileRef, &irect, NULL);    // QuickTime call
  186.         FSClose(fileRef);    // done with file
  187.     }
  188.  
  189.     // now going from 32x32 input image
  190.     irect = orect;
  191.  
  192.     // Create/Open resource fork of image file, in order to add icl resources
  193.     fileRef = kRsrcFileClosed;
  194.     if (!anError)
  195.     {
  196.         // try to create new file...
  197.         FSpCreateResFile(fsFile, (**gPrefs2Use_h).pictFileCreator, 'PICT', (ScriptCode)0);
  198.         anError = ResError();
  199.         // whether created or already there, open resource fork
  200.         fileRef = FSpOpenResFile(fsFile, fsRdWrPerm);
  201.         anError = ResError();
  202.     }
  203.  
  204.     // loop through each icon depth
  205.     if (!anError)
  206.     { // if opened ok
  207.         for (iconCounter=1; iconCounter <= 6 && !anError; iconCounter++)
  208.         {
  209.             switch(iconCounter)
  210.             {
  211.             case 1:
  212.                 theRsrcType = large1BitMask;
  213.                 theWidth = 32;
  214.                 theHeight = 32;
  215.                 SetRect(&orect, 0, 0, theWidth, theHeight);
  216.                 theDepth = 1;
  217.                 bytesPerRow = 4;
  218.                 theSize = theHeight*bytesPerRow*2;    // x2 'cause icon+mask
  219.                 break;
  220.             case 2:
  221.                 theRsrcType = large4BitData;
  222.                 theWidth = 32;
  223.                 theHeight = 32;
  224.                 SetRect(&orect, 0, 0, theWidth, theHeight);
  225.                 theDepth = 4;
  226.                 bytesPerRow = 16;
  227.                 theSize = theHeight*bytesPerRow;
  228.                 break;
  229.             case 3:
  230.                 theRsrcType = large8BitData;
  231.                 theWidth = 32;
  232.                 theHeight = 32;
  233.                 SetRect(&orect, 0, 0, theWidth, theHeight);
  234.                 theDepth = 8;
  235.                 bytesPerRow = 32;
  236.                 theSize = theHeight*bytesPerRow;
  237.                 break;
  238.             case 4:
  239.                 theRsrcType = small1BitMask;
  240.                 theWidth = 16;
  241.                 theHeight = 16;
  242.                 SetRect(&orect, 0, 0, theWidth, theHeight);
  243.                 theDepth = 1;
  244.                 bytesPerRow = 2;
  245.                 theSize = theHeight*bytesPerRow*2;    // x2 'cause icon+mask
  246.                 break;
  247.             case 5:
  248.                 theRsrcType = small4BitData;
  249.                 theWidth = 16;
  250.                 theHeight = 16;
  251.                 SetRect(&orect, 0, 0, theWidth, theHeight);
  252.                 theDepth = 4;
  253.                 bytesPerRow = 8;
  254.                 theSize = theHeight*bytesPerRow;
  255.                 break;
  256.             case 6:
  257.                 theRsrcType = small8BitData;
  258.                 theWidth = 16;
  259.                 theHeight = 16;
  260.                 SetRect(&orect, 0, 0, theWidth, theHeight);
  261.                 theDepth = 8;
  262.                 bytesPerRow = 16;
  263.                 theSize = theHeight*bytesPerRow;
  264.                 break;
  265.             } // switch
  266.     
  267.             // create a gworld to draw into
  268.             anError = NewGWorld(&iconGWorld, theDepth, &orect, (CTabHandle)NULL, (GDHandle)NULL, (GWorldFlags)0);
  269.             if (!anError)
  270.             {
  271.                 SetGWorld(iconGWorld, (GDHandle)NULL);
  272.                 LockPixels(iconGWorld->portPixMap);
  273.                 // put the image into the destination (iconWorld)
  274.                 CopyBits((BitMap *)*imageWorld->portPixMap,
  275.                         (BitMap *)*iconGWorld->portPixMap,
  276.                         &irect, &orect,
  277.                         ditherCopy, NULL);
  278.  
  279.                 // Draw border and folded document corner on iconWorld
  280.                 if (!anError)
  281.                 {
  282.                     // outer border
  283.                     FrameRect(&orect);
  284.                     // upper folded corner
  285.                     SetRect(&maxRect,((theWidth*3)/4)+1,-1,theWidth+1,(theHeight>>2)-1);
  286.                     // erase upper corner to white
  287.                     EraseRect(&maxRect);
  288.                     // draw lower folded corner
  289.                     FrameRect(&maxRect);
  290.                     // draw diagonal line
  291.                     MoveTo(((theWidth*3)/4)+1, 0);
  292.                     LineTo(theWidth, (theHeight>>2)-1);
  293.                 }
  294.  
  295.                 if ((destIconRsrc=NewHandle(theSize)) != NULL)
  296.                 {
  297.                     HLock(destIconRsrc);
  298.                     rowBytes = (*iconGWorld->portPixMap)->rowBytes & 0x3fff;
  299.                     srcPixPtr = GetPixBaseAddr(iconGWorld->portPixMap);
  300.                     tempDestPixPtr = StripAddress(*destIconRsrc);
  301.                     mmumode = true32b;
  302.                     SwapMMUMode(&mmumode);    // into 32 bit mode
  303.                     for (i=0; i < orect.bottom; i++)
  304.                     {
  305.                         tempSrcPixPtr = srcPixPtr;
  306.                         for (j=0; j < bytesPerRow; j++) 
  307.                             *tempDestPixPtr++ = *tempSrcPixPtr++;
  308.                         srcPixPtr += rowBytes;
  309.                     }
  310.                     // in 1 bit depth, fill the icon mask too
  311.                     if (theDepth == 1)
  312.                     {
  313.                         if (bytesPerRow <= 2)
  314.                             theCorner = 0xfC;    // small corner (1111 1100)
  315.                         else
  316.                             theCorner = 0xC0;    // regular corner (1100 0000)
  317.                         for (i=0; i < orect.bottom; i++)
  318.                         {
  319.                             for (j=0; j < (bytesPerRow-1); j++) 
  320.                                 *tempDestPixPtr++ = 0xff;
  321.                             *tempDestPixPtr++ = theCorner;
  322.                             theCorner >>= 1; // roll the corner mask over bit by bit
  323.                         }
  324.                     }
  325.                     SwapMMUMode(&mmumode);    // restore original mode
  326.  
  327.                     // as long as there are old icon resources, delete them..
  328.                     do {
  329.                         tmpHandle = Get1Resource(theRsrcType, kCustomIconResource);
  330.                         if (tmpHandle != NULL)
  331.                         {
  332.                             RemoveResource(tmpHandle);
  333.                             DisposeHandle(tmpHandle);
  334.                         }
  335.                     } while (tmpHandle != NULL);
  336.                     UpdateResFile(fileRef);
  337.  
  338.                     HUnlock(destIconRsrc);
  339.                     AddResource(destIconRsrc, theRsrcType, kCustomIconResource, NULL);
  340.                     anError = ResError();
  341.                     if (!anError)
  342.                     {
  343.                         WriteResource(destIconRsrc);
  344.                         ReleaseResource(destIconRsrc);
  345.                     }
  346.                 }
  347.  
  348.                 // done with the icon-copy gworld, away with it
  349.                 if (iconGWorld)
  350.                 {
  351.                     DisposeGWorld(iconGWorld);
  352.                     iconGWorld = NULL;
  353.                 }
  354.             }
  355.         } // for
  356.  
  357.         // close our resource file now
  358.         if (fileRef != kRsrcFileClosed)
  359.             {
  360.             UpdateResFile(fileRef);
  361.             anError = ResError();
  362.             CloseResFile(fileRef);
  363.             }
  364.  
  365.         // Turn on the FinderInfo flag to display the custom icon suite
  366.         if (!anError)
  367.             anError = FSpGetFInfo(fsFile,&finfo);
  368.         if (!anError)
  369.         {
  370.             finfo.fdFlags |= kHasCustomIcon;    // turn on hasCustomIcon flag
  371.             FSpSetFInfo(fsFile, &finfo);
  372.         }
  373.     } // if opened ok
  374.  
  375.     // switch back to previous resource file as current
  376.     UseResFile(oldResFile);
  377.  
  378.     // make double-sure to clean up after ourselves
  379.     if (iconGWorld)
  380.         DisposeGWorld(iconGWorld);
  381.     if (imageWorld)
  382.         DisposeGWorld(imageWorld);
  383.     
  384.     return anError;
  385.  
  386. } // AppendFinderIcons2PictF
  387.  
  388.  
  389.  
  390. /*
  391. ******************************************************************************
  392. Name:
  393.     CompressPictF
  394. ------------------------------------------------------------------------------
  395. Purpose:
  396.     Compresses a PICT data file using QuickTime
  397. ------------------------------------------------------------------------------
  398. Description:
  399.     ** How it does it
  400. ------------------------------------------------------------------------------
  401. Parameters:
  402. ------------------------------------------------------------------------------
  403. When Used:
  404.     ** who calls me and why/when
  405. ******************************************************************************
  406. */
  407. OSErr CompressPictF(ComponentInstance ci, FSSpec *theImageFile)
  408. {
  409.     OSErr                anError;
  410.     short                theFileRefNum;
  411. //    ProgressProcRecord    *progP,progressRec;
  412.  
  413.     /* Set up a progress dialog for display during compression */
  414. // later..
  415. //    progressRec.progressProc = Progress;
  416. //    progressRec.progressRefCon = 0;
  417. //    progP = &progressRec;
  418.  
  419.     /* open the picture file, prepare to compress in place */
  420.     anError = FSpOpenDF(theImageFile, fsRdWrPerm, &theFileRefNum);
  421.  
  422.     /* now compress the picture */
  423.     if (!anError)
  424.     {
  425.         /* Call QuickTime to do its magic.. */
  426.         anError = SCCompressPictureFile(
  427.             ci,
  428.             theFileRefNum,                /* fileRef of source picture file */
  429.             theFileRefNum);                /* fileRef of destination picture file (in place if same as src) */
  430.  
  431.         FSClose(theFileRefNum);
  432.     }
  433.  
  434.     /* force disk update */
  435. //    FlushVol(NULL, theImageFile->vRefNum); -- 5/26/93 [esp] commented out, not needed?
  436.  
  437.     return(anError);
  438. } // CompressPictF
  439.     
  440.