mirror of
https://github.com/darlinghq/darling-cocotron.git
synced 2024-11-26 21:40:44 +00:00
228 lines
7.9 KiB
Objective-C
228 lines
7.9 KiB
Objective-C
#import <Foundation/NSArray.h>
|
|
#import <Onyx2D/O2Function+PDF.h>
|
|
#import <Onyx2D/O2PDFArray.h>
|
|
#import <Onyx2D/O2PDFContext.h>
|
|
#import <Onyx2D/O2PDFDictionary.h>
|
|
#import <Onyx2D/O2PDFFunction_Type0.h>
|
|
#import <Onyx2D/O2PDFFunction_Type2.h>
|
|
#import <Onyx2D/O2PDFFunction_Type3.h>
|
|
#import <Onyx2D/O2PDFFunction_Type4.h>
|
|
#import <Onyx2D/O2PDFStream.h>
|
|
|
|
@implementation O2Function (PDF)
|
|
|
|
- initWithDomain: (O2PDFArray *) domain range: (O2PDFArray *) range {
|
|
if (![domain getNumbers: &_domain count: &_domainCount]) {
|
|
[self dealloc];
|
|
return nil;
|
|
}
|
|
|
|
[range getNumbers: &_range count: &_rangeCount];
|
|
|
|
return self;
|
|
}
|
|
|
|
- (O2PDFObject *) encodeReferenceWithContext: (O2PDFContext *) context {
|
|
NSInteger i, numberOfSamples = 1024, numberOfChannels = _rangeCount / 2;
|
|
O2PDFStream *result = [O2PDFStream pdfStream];
|
|
O2PDFDictionary *dictionary = [result dictionary];
|
|
unsigned char samples[numberOfSamples * numberOfChannels];
|
|
|
|
[dictionary setIntegerForKey: "FunctionType" value: 0];
|
|
[dictionary
|
|
setObjectForKey: "Domain"
|
|
value: [O2PDFArray pdfArrayWithNumbers: _domain
|
|
count: _domainCount]];
|
|
[dictionary setObjectForKey: "Range"
|
|
value: [O2PDFArray pdfArrayWithNumbers: _range
|
|
count: _rangeCount]];
|
|
[dictionary
|
|
setObjectForKey: "Size"
|
|
value: [O2PDFArray pdfArrayWithIntegers: &numberOfSamples
|
|
count: 1]];
|
|
[dictionary setIntegerForKey: "BitsPerSample" value: 8];
|
|
[dictionary setIntegerForKey: "Order" value: 1];
|
|
for (i = 0; i < numberOfSamples; i++) {
|
|
O2Float x = _domain[0] + ((O2Float) i / (O2Float) numberOfSamples) *
|
|
(_domain[1] - _domain[0]);
|
|
O2Float output[numberOfChannels];
|
|
int j;
|
|
|
|
O2FunctionEvaluate(self, x, output);
|
|
|
|
for (j = 0; j < numberOfChannels; j++) {
|
|
samples[i * numberOfChannels + j] =
|
|
((output[j] - _range[j * 2]) /
|
|
(_range[j * 2 + 1] - _range[j * 2])) *
|
|
255;
|
|
}
|
|
}
|
|
[[result mutableData] appendBytes: samples
|
|
length: numberOfSamples * numberOfChannels];
|
|
|
|
return [context encodeIndirectPDFObject: result];
|
|
}
|
|
|
|
+ (O2Function *) createFunctionWithDictionary: (O2PDFDictionary *) dictionary {
|
|
O2PDFInteger type;
|
|
O2PDFArray *domain;
|
|
O2PDFArray *range;
|
|
|
|
if (![dictionary getIntegerForKey: "FunctionType" value: &type]) {
|
|
NSLog(@"Function missing FunctionType");
|
|
return nil;
|
|
}
|
|
|
|
if (![dictionary getArrayForKey: "Domain" value: &domain]) {
|
|
NSLog(@"Function missing Domain");
|
|
return nil;
|
|
}
|
|
|
|
if (![dictionary getArrayForKey: "Range" value: &range])
|
|
range = nil;
|
|
|
|
if (type == 0) {
|
|
NSLog(@"Sampled functions unimplemented");
|
|
return nil;
|
|
} else if (type == 2) {
|
|
O2PDFArray *C0;
|
|
O2PDFArray *C1;
|
|
O2PDFReal N;
|
|
|
|
if (![dictionary getArrayForKey: "C0" value: &C0]) {
|
|
NSLog(@"No C0");
|
|
C0 = nil;
|
|
}
|
|
if (![dictionary getArrayForKey: "C1" value: &C1]) {
|
|
NSLog(@"No C1");
|
|
C1 = nil;
|
|
}
|
|
if (![dictionary getNumberForKey: "N" value: &N]) {
|
|
NSLog(@"Type 2 function missing N");
|
|
return nil;
|
|
}
|
|
|
|
return [[[O2PDFFunction_Type2 alloc] initWithDomain: domain
|
|
range: range
|
|
C0: C0
|
|
C1: C1
|
|
N: N] autorelease];
|
|
} else if (type == 3) {
|
|
O2PDFArray *functionsArray;
|
|
NSMutableArray *functions;
|
|
int i, count;
|
|
O2PDFArray *bounds;
|
|
O2PDFArray *encode;
|
|
|
|
if (![dictionary getArrayForKey: "Functions" value: &functionsArray]) {
|
|
NSLog(@"Functions entry missing from stitching function");
|
|
return nil;
|
|
}
|
|
count = [functionsArray count];
|
|
functions = [NSMutableArray arrayWithCapacity: count];
|
|
for (i = 0; i < count; i++) {
|
|
O2PDFDictionary *subfnDictionary;
|
|
O2Function *subfn;
|
|
|
|
if (![functionsArray getDictionaryAtIndex: i
|
|
value: &subfnDictionary]) {
|
|
NSLog(@"Functions[%d] not a dictionary", i);
|
|
return nil;
|
|
}
|
|
|
|
if ((subfn = [O2Function
|
|
createFunctionWithDictionary: subfnDictionary]) == nil)
|
|
return nil;
|
|
|
|
[functions addObject: subfn];
|
|
}
|
|
|
|
if (![dictionary getArrayForKey: "Bounds" value: &bounds])
|
|
return nil;
|
|
if (![dictionary getArrayForKey: "Encode" value: &encode])
|
|
return nil;
|
|
|
|
return [[[O2PDFFunction_Type3 alloc] initWithDomain: domain
|
|
range: range
|
|
functions: functions
|
|
bounds: bounds
|
|
encode: encode]
|
|
autorelease];
|
|
} else if (type == 4) {
|
|
NSLog(@"PostScript calculator functions unimplemented");
|
|
return nil;
|
|
}
|
|
|
|
return nil;
|
|
}
|
|
|
|
+ (O2Function *) createFunctionWithStream: (O2PDFStream *) stream {
|
|
O2PDFDictionary *dictionary = [stream dictionary];
|
|
O2PDFInteger type;
|
|
O2PDFArray *domain;
|
|
O2PDFArray *range;
|
|
|
|
if (![dictionary getIntegerForKey: "FunctionType" value: &type]) {
|
|
NSLog(@"Function missing FunctionType");
|
|
return nil;
|
|
}
|
|
|
|
if (![dictionary getArrayForKey: "Domain" value: &domain]) {
|
|
NSLog(@"Function missing Domain");
|
|
return nil;
|
|
}
|
|
|
|
if (![dictionary getArrayForKey: "Range" value: &range])
|
|
range = nil;
|
|
|
|
if (type == 0) {
|
|
O2PDFArray *size;
|
|
O2PDFInteger bitsPerSample;
|
|
O2PDFInteger order = 1;
|
|
O2PDFArray *encode = NULL;
|
|
O2PDFArray *decode = NULL;
|
|
|
|
if (![dictionary getArrayForKey: "Size" value: &size]) {
|
|
O2PDFError(__FILE__, __LINE__,
|
|
@"Size entry not present in Type0 function");
|
|
return nil;
|
|
}
|
|
|
|
if (![dictionary getIntegerForKey: "BitsPerSample"
|
|
value: &bitsPerSample]) {
|
|
O2PDFError(__FILE__, __LINE__,
|
|
@"BitsPerSample entry not present in Type0 function");
|
|
return nil;
|
|
}
|
|
|
|
[dictionary getIntegerForKey: "Order" value: &order];
|
|
if (order == 3)
|
|
O2PDFFix(__FILE__, __LINE__,
|
|
@"Cubic spline interpolation unimplemented in Type0 "
|
|
@"functions");
|
|
|
|
[dictionary getArrayForKey: "Encode" value: &encode];
|
|
[dictionary getArrayForKey: "Decode" value: &decode];
|
|
|
|
return [[O2PDFFunction_Type0 alloc] initWithDomain: domain
|
|
range: range
|
|
size: size
|
|
bitsPerSample: bitsPerSample
|
|
order: order
|
|
encode: encode
|
|
decode: decode
|
|
data: [stream data]];
|
|
}
|
|
|
|
if (type == 4) {
|
|
return [[O2PDFFunction_Type4 alloc] initWithDomain: domain
|
|
range: range
|
|
calculator: [stream data]];
|
|
}
|
|
|
|
NSLog(@"Unknown function type in stream=%d", type);
|
|
return nil;
|
|
}
|
|
|
|
@end
|