This is PICTFile.m in view mode; [Download] [Up]
/***********************************************************************\ PICT file class for Convert PICT which converts graphics from PICT to eps formats. Copyright (C) 1993 David John Burrowes This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 1, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. The author, David John Burrowes, can be reached at: davidjohn@kira.net.netcom.com David John Burrowes 1926 Ivy #10 San Mateo, CA 94403-1367 \***********************************************************************/ /* ==================================================================== This is the implementation file for the PICTFile class. Full documentation for this class can be found in the PICTFile.rtf file. I will not duplicate all that fine information here. This is $Revision: 1.10 $ of this file It was last modified by $Author: death $ on $Date: 93/04/04 23:29:46 $ Note that this file was created while using the New Century Schoolbook Roman typeface. You may find that some things line up strangely if you don't use that family. * $Log: PICTFile.m,v $ Revision 1.10 93/04/04 23:29:46 death Sun Apr 4 23:29:45 PDT 1993 Revision 1.9 93/01/09 21:07:04 death Sat Jan 9 21:07:04 PST 1993 Revision 1.8 93/01/01 11:51:13 death Fri Jan 1 11:51:12 PST 1993 Revision 1.7 92/12/31 15:34:01 death Thu Dec 31 15:34:01 PST 1992 Revision 1.6 92/12/05 23:06:55 death Sat Dec 5 23:06:54 PST 1992 Revision 1.5 92/12/03 18:01:12 death Thu Dec 3 18:01:11 PST 1992 Revision 1.4 92/11/27 19:37:24 death Fri Nov 27 19:37:24 PST 1992 Revision 1.3 92/11/08 09:26:15 death Sun Nov 8 09:26:15 PST 1992 Revision 1.2 92/08/09 19:46:19 death Sun Aug 9 19:46:19 PDT 1992 Revision 1.1 92/08/09 08:53:00 death Sun Aug 9 08:52:59 PDT 1992 *==================================================================== */ // // Import our own definition // #import "PICTFile.h" #import <architecture/byte_order.h> // for big/little endian conversins @implementation PICTFile ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Routine: free // Parameters: none // Returns: self // Stores: none // Description: // Frees various data owned by the instance. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - free { if (PICTHeader != NullByteString) FreeByteString(PICTHeader); if (BoundingRect != (PICTRect*) NullByteString) FreeByteString((ByteString)BoundingRect); return [super free]; } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Routine: OpenWithAccess: // Parameters: the means of accessing the specified file // Returns: self // Stores: none // Description: // This is a simple subclass-ed method from the File class. This simply traps to // make sure that the operation is not one that involves file writing, as this is not // supported at present by the PICTFile class. If it is an operation involving // writing, and error is set, and this returns self. // Bugs: // We don't check for errors when reading the header or opcodes or anything... ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - OpenWithAccess: (AccessType) operation { PICTOpcode theOpcode; [self ResetResults]; if (operation != FILE_READ) { [self StoreErrorCode: ERR_MAYNOTWRITE AndText: "You may ONLY read from a PICT file."]; } else { [super OpenWithAccess: operation]; if ([self GetErrorCode] == ERR_OK) { PICTHeader = NewByteString(512); [self Read: 512 BytesInto: PICTHeader]; [self AdvanceBytes: 2]; // skip the size BoundingRect = [self GetRect]; // // 92.12.03 djb Added because I found a Superpaint doc which had a large // number of 0's after the bounding rect. Weird. // do { theOpcode = [self GetOpcode]; } while( (theOpcode == 0) && ([self GetErrorCode] != ERR_EOF)); if (theOpcode == 0x11) { switch ([self GetByte]) { case 0x01: PICTVersion = 1; break; case 0x02: PICTVersion = 2; break; } } if (PICTVersion == 0) { PICTVersion = 9999; // unlikely Apple will ever do a 9999 vers. =) [self StoreErrorCode: ERR_UNKNOWNVERSION AndText: "Unknown PICT version!"]; } } } return self; } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Routine: initAndUse: // Parameters: none // Returns: self // Stores: none // Description: // This is a simple subclass-ed method from the File class. We subclass it // because we need to initalize our instance variables. // Bugs: // We don't initalize the bounding rect ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - initAndUse: (roCString) pathname { [super initAndUse: pathname]; PICTHeader = NullByteString; PICTVersion = 0; FoundEnd = NO; return self; } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Routine: initAndUseTemporary // Parameters: none // Returns: self // Stores: none // Description: // This is a simple subclass-ed method from the File class. This method essentially // implies doing write access to a file, which we don't presently support, so we just // return an error indirectly by setting FoundEnd to be YES. // Bugs: // We should be setting an error here. // We don't initalize the bounding rect ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - initAndUseTemporary { [super initAndUseTemporary]; PICTHeader = NullByteString; PICTVersion = 0; FoundEnd = YES; return self; } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Routine: GetVersion // Parameters: none // Returns: an integer representing the PICT file version number // Stores: none // Description: // Returns the version number of the PICT file to the caller. // Bugs: ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - (Integer) GetVersion { return PICTVersion; } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Routine: GetHeader // Parameters: none // Returns: A pointer to a block of constant data that is a copy of the 512byte // pict file header. // Stores: none // Description: // Returns a pointer to the 512 byte header of the PICT file. The 512 bytes are // not terminated in any way, and it is assumed the caller is aware of this. // Bugs: ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - (ConstByteString) GetHeader { return PICTHeader; } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Routine: GetBounds // Parameters: none // Returns: A pointer to a new struct describing the bounds of the pict file // Stores: none // Description: // Returns a rectangle struct to the caller containing the boundrary rectangl // of the PICT image in this PICT file. The caller is responsible for disposing of // the rectangle. // Bugs: // We blindly assume the memory allocation worked. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - (PICTRect*) GetBounds { PICTRect* tempRect; tempRect = (PICTRect*) NewByteString(sizeof(PICTRect)); tempRect->left = BoundingRect->left; tempRect->right = BoundingRect->right; tempRect->top = BoundingRect->top; tempRect->bottom = BoundingRect->bottom; return tempRect; } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Routine: GetOpcode // Parameters: none // Returns: A PICT opcode // Stores: none // Description: // Reads the next opcode from the PICT file and returns it. This reads either a // one or two byte opcode, depending on whether it's version 1 or 2 (or above). If // the version is 2 or above, it will also automatically move to the next even word // boundrary to read the next opcode. // History: // 93.08.01 djb Added NXSwap code for endianness // 93.08.15 djb Argh! I need to be casting the results!!! // Bugs: // By always returning the FF opcode when we've reached the end, things must // be carefull that they don't loop forever somehow.... ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - (PICTOpcode) GetOpcode { PICTOpcode theOpcode; if (FoundEnd == YES) theOpcode = 0xFF; else { switch (PICTVersion) { case 0: case 1: theOpcode = [self ReadByte]; break; case 2: // // Pict 2 opcodes always occur on 16 bit boundaries. If we aren't on // an even byte number, then scoot forward a byte. // if (EvenUnsignedNum([self GetCurrentPosition]) != YES) [self AdvanceBytes: 1]; [self Read: 2 BytesInto: (ByteString) &theOpcode]; theOpcode = (PICTOpcode)NXSwapBigShortToHost(theOpcode); break; default: // // if we don't know the current version, try to quit with the quit opcode. // theOpcode = 0xFF; FoundEnd = YES; break; } if (theOpcode == 0xFF) FoundEnd = YES; } return theOpcode; } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Routine: GetRect // Parameters: none // Returns: A Pict rectangle (ptr to) (or pass NULL if an erorr occurred) // Stores: none // Description: // Reads an 8 byte PICT rectangle from the PICT file, and returns this // copy to the caller. // History: // 93.08.01 djb Added NXSwap code for endianness // 93.08.15 djb Argh! I need to be casting the results!!! // 93.08.16 djb Argh! again! Wasn't casting properly in all cases. // Bugs: // We set no error codes. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - (PICTRect*) GetRect { PICTRect* tempRect; tempRect = (PICTRect*) NewByteString(sizeof(PICTRect)); [self Read: 8 BytesInto: (ByteString) tempRect]; tempRect->left = (INTEGER) NXSwapBigShortToHost(tempRect->left); tempRect->right = (INTEGER) NXSwapBigShortToHost(tempRect->right); tempRect->top = (INTEGER) NXSwapBigShortToHost(tempRect->top); tempRect->bottom = (INTEGER) NXSwapBigShortToHost(tempRect->bottom); if ([self GetErrorCode] != ERR_OK) { FreeByteString((ByteString) tempRect); tempRect = NULL; } return tempRect; } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Routine: GetPoint // Parameters: none // Returns: A Pict point (ptr to) (or pass NULL if an erorr occurred) // Stores: none // Description: // Reads a 4 byte point from the PICT file and returns a copy to the caller. // History: // 93.08.01 djb Added NXSwap code for endianness // 93.08.15 djb Argh! I need to be casting the results!!! // 93.08.16 djb Argh! again! Wasn't casting properly in all cases. // Bugs: // We set no error codes. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - (PICTPoint*) GetPoint { PICTPoint* tempPt; tempPt = (PICTPoint*) NewByteString(sizeof(PICTPoint)); [self Read: 4 BytesInto: (ByteString)tempPt]; tempPt->x = (INTEGER) NXSwapBigShortToHost(tempPt->x); tempPt->y = (INTEGER) NXSwapBigShortToHost(tempPt->y); if ([self GetErrorCode] != ERR_OK) { FreeByteString((ByteString) tempPt); tempPt = NULL; } return tempPt; } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Routine: GetByte // Parameters: none // Returns: A byte // Stores: none // Description: // This is just like ReadByte in the File class. It reads a byte and returns it // to the caller. This is provided for naming consistancy with the other methods here. // Bugs: ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - (Byte) GetByte { return [self ReadByte]; } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Routine: GetSignedByte // Parameters: none // Returns: A byte // Stores: none // Description: // This is just like ReadByte in the File class. It reads a byte and returns it // to the caller. This is provided for naming consistancy with the other methods here. // Bugs: ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - (SignedByte) GetSignedByte { return (SignedByte) [self ReadByte]; } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Routine: GetPString // Parameters: none // Returns: A CString, or a NullCString if a problem occurred. // Stores: none // Description: // This reads in a Pascal style string from the PICT file, and returns the copy // as a CString structure to the caller (who is responsible for disposing of it) // Note, though, thatthe file reading routines it calls may store errors... // Bugs: // Not checking them error codes again.... ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - (CString) GetPString { Byte length; CString theString; length = [self ReadByte]; theString = NewCString(length); [self Read: length BytesInto: (ByteString) theString]; theString[length] = EndOfCString; return theString; } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Routine: GetINTEGER // Parameters: none // Returns: An integer // Stores: none // Description: // This reads a 2 byte signed integer in and then returns it to the caller as an // Integer type // History: // 93.08.01 djb Added NXSwap code for endianness // 93.08.15 djb Argh! I need to be casting the results!!! // 93.08.16 djb Argh! again! Wasn't casting properly in all cases. // Bugs: ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - (Integer) GetINTEGER { Signed16Bits theInt; [self Read: 2 BytesInto: (ByteString) &theInt]; return (INTEGER) NXSwapBigShortToHost(theInt); } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Routine: GetPositiveINTEGER // Parameters: none // Returns: A positive integer // Stores: none // Description: // This reas a 2 byte signed integer in and then returns it to the caller as a // PositiveInteger type. // History: // 93.08.01 djb Added NXSwap code for endianness // 93.08.15 djb Argh! I need to be casting the results!!! // 93.08.16 djb Argh! again! Wasn't casting properly in all cases. // Bugs: ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - (PositiveInteger) GetPositiveINTEGER { bits16 theInt; [self Read: 2 BytesInto: (ByteString) &theInt]; return (bits16) NXSwapBigShortToHost(theInt); } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Routine: GetLONGINT // Parameters: none // Returns: A long int // Stores: none // Description: // This reads a 4 byte signed integer in and then returns it to the caller as an // Integer type. // History: // 93.08.01 djb Added NXSwap code for endianness // 93.08.15 djb Argh! I need to be casting the results!!! // 93.08.16 djb Argh! again! Wasn't casting properly in all cases. // Bugs: ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - (Integer) GetLONGINT { Signed32Bits theInt; [self Read: 4 BytesInto: (ByteString) &theInt]; return (LONGINT) NXSwapBigLongToHost(theInt); } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Routine: GetPositiveLONGINT // Parameters: none // Returns: A positive integer // Stores: none // Description: // This reas a 2 byte signed integer in and then returns it to the caller as a // PositiveInteger type. // History: // 93.08.01 djb Added NXSwap code for endianness // 93.08.15 djb Argh! I need to be casting the results!!! // 93.08.16 djb Argh! again! Wasn't casting properly in all cases. // Bugs: ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - (PositiveInteger) GetPositiveLONGINT { bits32 theInt; [self Read: 4 BytesInto: (ByteString) &theInt]; return (bits32) NXSwapBigLongToHost(theInt); } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Routine: GetFixedNumber // Parameters: none // Returns: A real number // Stores: none // Description: // This reas a 4 byte signed integer in and then converts it to the fixed pont number // it really is by shoving a decimal point in after the 16th bit, and returning as // a real number.. // History: // 93.08.01 djb Added NXSwap code for endianness // 93.08.15 djb Argh! I need to be casting the results!!! // 93.08.16 djb Argh! again! Wasn't casting properly in all cases. // Bugs: ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - (Real) GetFixedNumber { Signed32Bits fixedNumber; [self Read: 4 BytesInto: (ByteString) &fixedNumber]; fixedNumber = (LONGINT) NXSwapBigLongToHost(fixedNumber); return fixedNumber / 65536.0; } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Routine: GetPolyVerbs // Parameters: none // Returns: an 8 bit bitfield of options for drawing a polygon. // Stores: none // Description: // This merly provides a way for the app to read in the bitfield that is used for // one of the piccomments. This way if we need to ever tweak the data, we can do // it just here. // Bugs: // This does some really gross typecasting to convert the 1 byte value to a 1 byte // bitfield. I'm sure there are easier ways... ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - (TPolyVerbRec) GetPolyVerbs { TPolyVerbRec * dummy; Byte temp = [self ReadByte]; dummy = (TPolyVerbRec *) & temp; return *dummy; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.