diff --git a/CoreGraphics/CGImageDestination.h b/CoreGraphics/CGImageDestination.h index e40bb9ba..e1964920 100644 --- a/CoreGraphics/CGImageDestination.h +++ b/CoreGraphics/CGImageDestination.h @@ -6,21 +6,21 @@ typedef struct _O2ImageDestination *CGImageDestinationRef; #import #import -const CFStringRef kCGImageDestinationLossyCompressionQuality; -const CFStringRef kCGImageDestinationBackgroundColor; +COREGRAPHICS_EXPORT const CFStringRef kCGImageDestinationLossyCompressionQuality; +COREGRAPHICS_EXPORT const CFStringRef kCGImageDestinationBackgroundColor; -CFTypeID CGImageDestinationGetTypeID(void); +COREGRAPHICS_EXPORT CFTypeID CGImageDestinationGetTypeID(void); -CFArrayRef CGImageDestinationCopyTypeIdentifiers(void); +COREGRAPHICS_EXPORT CFArrayRef CGImageDestinationCopyTypeIdentifiers(void); -CGImageDestinationRef CGImageDestinationCreateWithData(CFMutableDataRef data,CFStringRef type,size_t imageCount,CFDictionaryRef options); -CGImageDestinationRef CGImageDestinationCreateWithDataConsumer(CGDataConsumerRef dataConsumer,CFStringRef type,size_t imageCount,CFDictionaryRef options); -CGImageDestinationRef CGImageDestinationCreateWithURL(CFURLRef url,CFStringRef type,size_t imageCount,CFDictionaryRef options); +COREGRAPHICS_EXPORT CGImageDestinationRef CGImageDestinationCreateWithData(CFMutableDataRef data,CFStringRef type,size_t imageCount,CFDictionaryRef options); +COREGRAPHICS_EXPORT CGImageDestinationRef CGImageDestinationCreateWithDataConsumer(CGDataConsumerRef dataConsumer,CFStringRef type,size_t imageCount,CFDictionaryRef options); +COREGRAPHICS_EXPORT CGImageDestinationRef CGImageDestinationCreateWithURL(CFURLRef url,CFStringRef type,size_t imageCount,CFDictionaryRef options); -void CGImageDestinationSetProperties(CGImageDestinationRef self,CFDictionaryRef properties); +COREGRAPHICS_EXPORT void CGImageDestinationSetProperties(CGImageDestinationRef self,CFDictionaryRef properties); -void CGImageDestinationAddImage(CGImageDestinationRef self,CGImageRef image,CFDictionaryRef properties); -void CGImageDestinationAddImageFromSource(CGImageDestinationRef self,CGImageSourceRef imageSource,size_t index,CFDictionaryRef properties); +COREGRAPHICS_EXPORT void CGImageDestinationAddImage(CGImageDestinationRef self,CGImageRef image,CFDictionaryRef properties); +COREGRAPHICS_EXPORT void CGImageDestinationAddImageFromSource(CGImageDestinationRef self,CGImageSourceRef imageSource,size_t index,CFDictionaryRef properties); -bool CGImageDestinationFinalize(CGImageDestinationRef self); +COREGRAPHICS_EXPORT bool CGImageDestinationFinalize(CGImageDestinationRef self); diff --git a/Foundation/platform_windows/NSRecursiveLock_win32.h b/Foundation/platform_windows/NSRecursiveLock_win32.h index d93d5b82..188a2471 100644 --- a/Foundation/platform_windows/NSRecursiveLock_win32.h +++ b/Foundation/platform_windows/NSRecursiveLock_win32.h @@ -5,11 +5,10 @@ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#import #import #import -@interface NSRecursiveLock_win32 : NSObject { +@interface NSRecursiveLock_win32 : NSRecursiveLock { CRITICAL_SECTION _lock; NSString *_name; } diff --git a/Onyx2D/O2DataProvider.h b/Onyx2D/O2DataProvider.h index 92a60cea..3b1cb039 100644 --- a/Onyx2D/O2DataProvider.h +++ b/Onyx2D/O2DataProvider.h @@ -39,7 +39,7 @@ CFDataRef O2DataProviderCopyData(O2DataProviderRef self); size_t O2DataProviderRewind(O2DataProviderRef self); size_t O2DataProviderGetBytesAtPosition(O2DataProviderRef self,void *buffer,size_t length,size_t position); -size_t O2DataProviderGetBytesAtPosition(O2DataProviderRef self,void *buffer,size_t length,size_t position); +size_t O2DataProviderGetBytes(O2DataProviderRef self,void *buffer,size_t length); -(NSInputStream *)inputStream; diff --git a/Onyx2D/O2ImageSource_JPEG.m b/Onyx2D/O2ImageSource_JPEG.m index 492d1b23..9b87018e 100644 --- a/Onyx2D/O2ImageSource_JPEG.m +++ b/Onyx2D/O2ImageSource_JPEG.m @@ -1059,14 +1059,15 @@ NSData *O2DCTDecode(NSData *data) { jpeg decoder; int width,height; int comp; - int bitsPerPixel=8; - int bytesPerRow=(bitsPerPixel/(sizeof(char)*8))*width; - void *bytes=stbi_jpeg_load_from_memory(&decoder,[data bytes],[data length],&width,&height,&comp,STBI_grey); + void *bytes=stbi_jpeg_load_from_memory(&decoder,[data bytes],[data length],&width,&height,&comp,STBI_default); + int bytesPerRow=comp*width; if(bytes==NULL) return nil; - return [[NSData alloc] initWithBytesNoCopy:bytes length:bytesPerRow*height]; + NSData *result=[[NSData alloc] initWithBytesNoCopy:bytes length:bytesPerRow*height]; + + return result; } +(BOOL)isPresentInDataProvider:(O2DataProvider *)provider { diff --git a/Onyx2D/O2LZW.h b/Onyx2D/O2LZW.h index 478b4b86..812197f7 100644 --- a/Onyx2D/O2LZW.h +++ b/Onyx2D/O2LZW.h @@ -53,5 +53,4 @@ typedef struct LZWFileType { } LZWFileType; - int DLZWSetupDecompress(LZWFileType * LZWFile); -int DLZWDecompressLine(LZWFileType * LZWFile,LZWPixelType * Line,int LineLen); \ No newline at end of file +NSData *LZWDecodeWithExpectedResultLength(NSData *data,unsigned stripLength); diff --git a/Onyx2D/O2LZW.m b/Onyx2D/O2LZW.m index 2ff3ab36..8ab15d65 100644 --- a/Onyx2D/O2LZW.m +++ b/Onyx2D/O2LZW.m @@ -22,6 +22,7 @@ THE SOFTWARE. */ #import +#import #define LZ_MAX_CODE 4095 /* Biggest code possible in 12 bits. */ #define LZ_BITS 12 @@ -153,7 +154,7 @@ static int DLZWGetPrefixChar(LZWPrefixType *Prefix,int Code,int ClearCode) { return Code; } -int DLZWDecompressLine(LZWFileType * LZWFile,LZWPixelType * Line,int LineLen) { +int DLZWDecompressLine(LZWFileType * LZWFile,O2DataConsumerRef consumer,int LineLen) { int i = 0; int j, CrntCode, EOFCode, ClearCode, CrntPrefix, LastCode, StackPtr; @@ -196,7 +197,10 @@ int DLZWDecompressLine(LZWFileType * LZWFile,LZWPixelType * Line,int LineLen) { } else { if (CrntCode < ClearCode) { /* This is simple - its pixel scalar, so add it to output: */ - Line[i] = CrntCode; + uint8_t bytes[1]; + bytes[0]=CrntCode; + O2DataConsumerPutBytes(consumer,bytes,1); + i++; } else #define RUNNING_CODE_MINUS 2 @@ -244,8 +248,11 @@ int DLZWDecompressLine(LZWFileType * LZWFile,LZWPixelType * Line,int LineLen) { /* Now lets pop all the stack into output: */ while (StackPtr != 0 && i < LineLen){ + uint8_t bytes[1]; + bytes[0]=Stack[--StackPtr]; + + O2DataConsumerPutBytes(consumer,bytes,1); - Line[i] = Stack[--StackPtr]; i++; } } @@ -272,3 +279,24 @@ int DLZWDecompressLine(LZWFileType * LZWFile,LZWPixelType * Line,int LineLen) { return GIF_OK; } +NSData *LZWDecodeWithExpectedResultLength(NSData *data,unsigned stripLength){ + NSMutableData *outputData=[NSMutableData data]; + O2DataConsumerRef consumer=O2DataConsumerCreateWithCFData(outputData); + LZWFileType lzwStream; + + lzwStream.inputStream=[NSInputStream inputStreamWithData:data]; + [lzwStream.inputStream open]; + lzwStream.PixelCount=stripLength; + + DLZWSetupDecompress(&lzwStream); + int error; + + if((error=DLZWDecompressLine(&lzwStream,consumer,stripLength))==0) + NSLog(@"error=%d",error); + + O2DataConsumerRelease(consumer); + + return outputData; +} + + diff --git a/Onyx2D/O2PDFFilter.m b/Onyx2D/O2PDFFilter.m index 9bf87bb8..17c045f9 100644 --- a/Onyx2D/O2PDFFilter.m +++ b/Onyx2D/O2PDFFilter.m @@ -15,6 +15,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI #import #import #import +#import #import #import @@ -36,7 +37,7 @@ NSData *O2PDFFilterWithName(const char *name,NSData *data,O2PDFDictionary *param } +(NSData *)LZWDecode_data:(NSData *)data parameters:(O2PDFDictionary *)parameters { - return nil; + return LZWDecodeWithExpectedResultLength(data,[data length]*10); } +(NSData *)decodeWithName:(const char *)name data:(NSData *)data parameters:(O2PDFDictionary *)parameters { @@ -45,6 +46,9 @@ NSData *O2PDFFilterWithName(const char *name,NSData *data,O2PDFDictionary *param else if((strcmp(name,"DCTDecode")==0) || (strcmp(name,"DCT")==0)){ return O2DCTDecode(data); } + else if((strcmp(name,"LZWDecode")==0) || (strcmp(name,"LZW")==0)){ + data=LZWDecodeWithExpectedResultLength(data,[data length]*10); + } else { O2PDFError(__FILE__,__LINE__,@"Unknown O2PDFFilter name = %s, parameters=%@",name,parameters); return nil; diff --git a/Onyx2D/O2PDFOperators.m b/Onyx2D/O2PDFOperators.m index d87edae0..d52c1f53 100644 --- a/Onyx2D/O2PDFOperators.m +++ b/Onyx2D/O2PDFOperators.m @@ -86,7 +86,7 @@ void O2PDF_render_BDC(O2PDFScanner *scanner,void *info) { // Begin inline image object void O2PDF_render_BI(O2PDFScanner *scanner,void *info) { - O2PDFFix(__FILE__,__LINE__,@"BI unimplemented"); +// do nothing, all the values are pushed on the stack and ID handles them } // Begin marked-content sequence @@ -362,7 +362,7 @@ void O2PDF_render_DP(O2PDFScanner *scanner,void *info) { // End inline image object void O2PDF_render_EI(O2PDFScanner *scanner,void *info) { - O2PDFFix(__FILE__,__LINE__,@"EI unimplemented"); +// do nothing, everything is implemented by ID, EI is a formality } // End marked-content sequence @@ -615,7 +615,76 @@ void O2PDF_render_i(O2PDFScanner *scanner,void *info) { // Begin inline image data void O2PDF_render_ID(O2PDFScanner *scanner,void *info) { - O2PDFFix(__FILE__,__LINE__,@"ID unimplemented"); + O2PDFDictionary *dictionary=[O2PDFDictionary pdfDictionary]; + + while(YES) { + O2PDFObject *value; + const char *key; + + if(!O2PDFScannerPopObject(scanner,&value)) + break; + + if(!O2PDFScannerPopName(scanner,&key)){ + O2PDFError(__FILE__,__LINE__,@"popName failed"); + break; + } + + [dictionary setObjectForKey:key value:value]; + } + + O2PDFInteger bitsPerComponent=0; + O2PDFObject *colorSpace=NULL; + O2PDFArray *decode=NULL; + O2PDFObject *decodeParms=NULL; + O2PDFObject *filter=NULL; + O2PDFInteger height=0; + O2PDFBoolean imageMask=NO; + const char *intent=NULL; + O2PDFBoolean interpolate=NO; + O2PDFInteger width=0; + + if(![dictionary getIntegerForKey:"BPC" value:&bitsPerComponent]) + if(![dictionary getIntegerForKey:"BitsPerComponent" value:&bitsPerComponent]){ + } + + if(![dictionary getObjectForKey:"CS" value:&colorSpace]) + if(![dictionary getObjectForKey:"ColorSpace" value:&colorSpace]){ + } + + if(![dictionary getArrayForKey:"D" value:&decode]) + if(![dictionary getArrayForKey:"Decode" value:&decode]){ + } + + if(![dictionary getObjectForKey:"DP" value:&decodeParms]) + if(![dictionary getObjectForKey:"DecodeParms" value:&decodeParms]){ + } + + if(![dictionary getObjectForKey:"F" value:&filter]) + if(![dictionary getObjectForKey:"Filter" value:&filter]){ + } + + if(![dictionary getIntegerForKey:"H" value:&height]) + if(![dictionary getIntegerForKey:"Height" value:&height]){ + } + + if(![dictionary getBooleanForKey:"IM" value:&imageMask]) + if(![dictionary getBooleanForKey:"ImageMask" value:&imageMask]){ + } + + if(![dictionary getObjectForKey:"Intent" value:&intent]) + + if(![dictionary getBooleanForKey:"I" value:&interpolate]) + if(![dictionary getBooleanForKey:"Interpolate" value:&interpolate]){ + } + + if(![dictionary getIntegerForKey:"W" value:&width]) + if(![dictionary getIntegerForKey:"Width" value:&width]){ + } + + size_t bytesPerRow=(width*bitsPerComponent)/8; + + NSData *data=O2PDFScannerCreateDataWithLength(scanner,height*bytesPerRow); + } // setlinejoin, Set line join style diff --git a/Onyx2D/O2PDFScanner.h b/Onyx2D/O2PDFScanner.h index f45b99b0..76dfaf7d 100644 --- a/Onyx2D/O2PDFScanner.h +++ b/Onyx2D/O2PDFScanner.h @@ -8,6 +8,10 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI #import +@class O2PDFScanner; + +typedef O2PDFScanner *O2PDFScannerRef; + @class NSData,NSMutableArray; @class O2PDFContentStream,O2PDFOperatorTable; @class O2PDFString,O2PDFArray,O2PDFDictionary,O2PDFStream,O2PDFxref,O2PDFObject_identifier; @@ -26,6 +30,8 @@ BOOL O2PDFParseIndirectObject(NSData *data,O2PDFInteger position,O2PDFObject **o O2PDFContentStream *_stream; O2PDFOperatorTable *_operatorTable; void *_info; + O2PDFInteger _currentStream; + O2PDFInteger _position; } -initWithContentStream:(O2PDFContentStream *)stream operatorTable:(O2PDFOperatorTable *)operatorTable info:(void *)info; @@ -42,6 +48,9 @@ BOOL O2PDFScannerPopArray(O2PDFScanner *scanner,O2PDFArray **value); BOOL O2PDFScannerPopDictionary(O2PDFScanner *scanner,O2PDFDictionary **value); BOOL O2PDFScannerPopStream(O2PDFScanner *scanner,O2PDFStream **value); +NSData *O2PDFScannerCreateDataWithLength(O2PDFScanner *scanner,size_t length); + + -(BOOL)scan; @end diff --git a/Onyx2D/O2PDFScanner.m b/Onyx2D/O2PDFScanner.m index 611eabe4..5983fe4e 100644 --- a/Onyx2D/O2PDFScanner.m +++ b/Onyx2D/O2PDFScanner.m @@ -1122,20 +1122,38 @@ BOOL O2PDFScannerPopStream(O2PDFScanner *self,O2PDFStream **value) { return [lastObject checkForType:kO2PDFObjectTypeStream value:value]; } +NSData *O2PDFScannerCreateDataWithLength(O2PDFScanner *self,size_t length) { + NSArray *streams=[self->_stream streams]; + O2PDFObject *object=[streams objectAtIndex:self->_currentStream]; + O2PDFStream *stream; + + if(![object checkForType:kO2PDFObjectTypeStream value:&stream]) + return nil; + + NSData *data=[stream data]; + + NSData *result=[data subdataWithRange:NSMakeRange(self->_position,length)]; + + self->_position+=length; + + return result; +} + -(BOOL)scanStream:(O2PDFStream *)stream { O2PDFxref *xref=[stream xref]; NSData *data=[stream data]; const char *bytes=[data bytes]; unsigned length=[data length]; - O2PDFInteger position=0; + + _position=0; if(O2PDFScannerDumpStream) NSLog(@"data[%d]=%@",[data length],[[[NSString alloc] initWithData:data encoding:NSISOLatin1StringEncoding] autorelease]); - while(position