home *** CD-ROM | disk | FTP | other *** search
/ Chip: Special Computer Graphics & Animation / Chip-Special-Computergrafik.bin / programs / povray / povsrc.sea / POVSRC / SOURCE / SaveCmpPict.c < prev    next >
Text File  |  1994-02-04  |  14KB  |  468 lines

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