diff --git a/DTImageToDataPatch.h b/DTImageToDataPatch.h
new file mode 100644
index 0000000..0c58ce7
--- /dev/null
+++ b/DTImageToDataPatch.h
@@ -0,0 +1,15 @@
+@interface DTImageToDataPatch : QCPatch
+{
+ QCImagePort *inputImage;
+ QCIndexPort *inputImageFileType;
+ QCVirtualPort *outputRawData;
+}
+
++(BOOL)isSafe;
++(BOOL)allowsSubpatchesWithIdentifier:(id)identifier;
++(QCPatchExecutionMode)executionModeWithIdentifier:(id)identifier;
++(QCPatchTimeMode)timeModeWithIdentifier:(id)identifier;
+-(id)initWithIdentifier:(id)identifier;
+-(BOOL)execute:(QCOpenGLContext*)context time:(double)time arguments:(NSDictionary*)arguments;
+
+@end
diff --git a/DTImageToDataPatch.m b/DTImageToDataPatch.m
new file mode 100644
index 0000000..004eed9
--- /dev/null
+++ b/DTImageToDataPatch.m
@@ -0,0 +1,53 @@
+#import "DTImageToDataPatch.h"
+
+@implementation DTImageToDataPatch
+
++(BOOL)isSafe
+{
+ return NO;
+}
+
++(BOOL)allowsSubpatchesWithIdentifier:(id)identifier
+{
+ return NO;
+}
+
++(QCPatchExecutionMode)executionModeWithIdentifier:(id)identifier
+{
+ return kQCPatchExecutionModeProcessor;
+}
+
++(QCPatchTimeMode)timeModeWithIdentifier:(id)identifier
+{
+ return kQCPatchTimeModeNone;
+}
+
+-(id)initWithIdentifier:(id)identifier
+{
+ if(self = [super initWithIdentifier:identifier])
+ {
+ [[self userInfo] setObject:@"Kineme Image To Data" forKey:@"name"];
+
+ [inputImageFileType setMaxIndexValue:NSJPEG2000FileType];
+ [inputImageFileType setIndexValue:NSPNGFileType];
+ }
+ return self;
+}
+
+-(BOOL)execute:(QCOpenGLContext*)context time:(double)time arguments:(NSDictionary*)arguments
+{
+ if ([inputImage wasUpdated] || [inputImageFileType wasUpdated])
+ {
+ NSBitmapImageFileType imageFileType = [inputImageFileType indexValue];
+ NSImage *image = [inputImage value];
+ NSArray *representations = [image representations];
+ NSData *data = [NSBitmapImageRep representationOfImageRepsInArray:representations
+ usingType:imageFileType
+ properties:nil];
+ [outputRawData setRawValue:data];
+ }
+
+ return YES;
+}
+
+@end
diff --git a/DTImageToDataPatch.xml b/DTImageToDataPatch.xml
new file mode 100644
index 0000000..cec963a
--- /dev/null
+++ b/DTImageToDataPatch.xml
@@ -0,0 +1,57 @@
+
+
+
+
+ nodeAttributes
+
+ name
+ Image To Data
+ categories
+
+ Kineme DataTools
+
+ copyright
+ Copyright 2011 Kosada Incorporated. All rights reserved.
+ description
+ This patch converts an image to raw data bytes.
+
+http://kineme.net/
+
+ inputAttributes
+
+ inputImage
+
+ name
+ Image
+ description
+ The image to convert
+
+ inputImageFileType
+
+ name
+ Image Representation
+ description
+ The image representation to use when converting to bytes
+ menu
+
+ TIFF
+ BMP
+ GIF
+ JPEG
+ PNG
+ JPEG2000
+
+
+
+ outputAttributes
+
+ outputRawData
+
+ name
+ Raw Data
+ description
+ The bytes of the image
+
+
+
+
diff --git a/DataTools.xcodeproj/project.pbxproj b/DataTools.xcodeproj/project.pbxproj
index c3c29cc..d89223d 100644
--- a/DataTools.xcodeproj/project.pbxproj
+++ b/DataTools.xcodeproj/project.pbxproj
@@ -87,6 +87,9 @@
E74FE0A015502957009E29D6 /* DTStringToDataPatch.m in Sources */ = {isa = PBXBuildFile; fileRef = E74FE09F15502957009E29D6 /* DTStringToDataPatch.m */; };
E74FE0A115502957009E29D6 /* DTStringToDataPatch.m in Sources */ = {isa = PBXBuildFile; fileRef = E74FE09F15502957009E29D6 /* DTStringToDataPatch.m */; };
E74FE0CB15502E3F009E29D6 /* DTStringToDataPatch.xml in Resources */ = {isa = PBXBuildFile; fileRef = E74FE0CA15502E3F009E29D6 /* DTStringToDataPatch.xml */; };
+ E74FE11F15505A7F009E29D6 /* DTImageToDataPatch.m in Sources */ = {isa = PBXBuildFile; fileRef = E74FE11E15505A7F009E29D6 /* DTImageToDataPatch.m */; };
+ E74FE12015505A7F009E29D6 /* DTImageToDataPatch.m in Sources */ = {isa = PBXBuildFile; fileRef = E74FE11E15505A7F009E29D6 /* DTImageToDataPatch.m */; };
+ E74FE12215505A8D009E29D6 /* DTImageToDataPatch.xml in Resources */ = {isa = PBXBuildFile; fileRef = E74FE12115505A8D009E29D6 /* DTImageToDataPatch.xml */; };
E78586E913E9F64A000BBF4B /* DTStructureKeyPatch.m in Sources */ = {isa = PBXBuildFile; fileRef = E78586E813E9F64A000BBF4B /* DTStructureKeyPatch.m */; };
E78586EB13E9F7DB000BBF4B /* DTStructureKeyPatch.xml in Resources */ = {isa = PBXBuildFile; fileRef = E78586EA13E9F7DB000BBF4B /* DTStructureKeyPatch.xml */; };
E785870513E9F967000BBF4B /* DTStructureKeyPatch.m in Sources */ = {isa = PBXBuildFile; fileRef = E78586E813E9F64A000BBF4B /* DTStructureKeyPatch.m */; };
@@ -194,6 +197,9 @@
E74FE09E15502957009E29D6 /* DTStringToDataPatch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DTStringToDataPatch.h; sourceTree = ""; };
E74FE09F15502957009E29D6 /* DTStringToDataPatch.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DTStringToDataPatch.m; sourceTree = ""; };
E74FE0CA15502E3F009E29D6 /* DTStringToDataPatch.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = DTStringToDataPatch.xml; sourceTree = ""; };
+ E74FE11D15505A7F009E29D6 /* DTImageToDataPatch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DTImageToDataPatch.h; sourceTree = ""; };
+ E74FE11E15505A7F009E29D6 /* DTImageToDataPatch.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DTImageToDataPatch.m; sourceTree = ""; };
+ E74FE12115505A8D009E29D6 /* DTImageToDataPatch.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = DTImageToDataPatch.xml; sourceTree = ""; };
E78586E713E9F64A000BBF4B /* DTStructureKeyPatch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DTStructureKeyPatch.h; sourceTree = ""; };
E78586E813E9F64A000BBF4B /* DTStructureKeyPatch.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DTStructureKeyPatch.m; sourceTree = ""; };
E78586EA13E9F7DB000BBF4B /* DTStructureKeyPatch.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = DTStructureKeyPatch.xml; sourceTree = ""; };
@@ -371,6 +377,7 @@
E7DC1662134E13A700DBDFC8 /* DTConvertToDataPatch.xml */,
E7DC1664134E13E600DBDFC8 /* DTConvertFromDataPatch.xml */,
E74FE0CA15502E3F009E29D6 /* DTStringToDataPatch.xml */,
+ E74FE12115505A8D009E29D6 /* DTImageToDataPatch.xml */,
);
name = XML;
sourceTree = "";
@@ -467,6 +474,8 @@
E7DC1621134E0F9E00DBDFC8 /* DTConvertFromDataPatch.m */,
E74FE09E15502957009E29D6 /* DTStringToDataPatch.h */,
E74FE09F15502957009E29D6 /* DTStringToDataPatch.m */,
+ E74FE11D15505A7F009E29D6 /* DTImageToDataPatch.h */,
+ E74FE11E15505A7F009E29D6 /* DTImageToDataPatch.m */,
);
name = Convert;
sourceTree = "";
@@ -572,6 +581,7 @@
E7DC1665134E13E600DBDFC8 /* DTConvertFromDataPatch.xml in Resources */,
E78586EB13E9F7DB000BBF4B /* DTStructureKeyPatch.xml in Resources */,
E74FE0CB15502E3F009E29D6 /* DTStringToDataPatch.xml in Resources */,
+ E74FE12215505A8D009E29D6 /* DTImageToDataPatch.xml in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -630,6 +640,7 @@
E72971A313B6ED0C001BBB7F /* DTStructureBreakOutPatchUI.m in Sources */,
E785870513E9F967000BBF4B /* DTStructureKeyPatch.m in Sources */,
E74FE0A115502957009E29D6 /* DTStringToDataPatch.m in Sources */,
+ E74FE12015505A7F009E29D6 /* DTImageToDataPatch.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -664,6 +675,7 @@
E7DC1622134E0F9E00DBDFC8 /* DTConvertFromDataPatch.m in Sources */,
E78586E913E9F64A000BBF4B /* DTStructureKeyPatch.m in Sources */,
E74FE0A015502957009E29D6 /* DTStringToDataPatch.m in Sources */,
+ E74FE11F15505A7F009E29D6 /* DTImageToDataPatch.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -687,7 +699,6 @@
INFOPLIST_FILE = Info.plist;
ONLY_ACTIVE_ARCH = NO;
PRODUCT_NAME = DataTools;
- RUN_CLANG_STATIC_ANALYZER = NO;
SDKROOT = macosx10.5;
};
name = Release;
@@ -738,7 +749,6 @@
);
PREBINDING = NO;
PRODUCT_NAME = Tests;
- RUN_CLANG_STATIC_ANALYZER = NO;
};
name = Release;
};
diff --git a/DataToolsPrincipal.m b/DataToolsPrincipal.m
index bdea035..2d3e25f 100644
--- a/DataToolsPrincipal.m
+++ b/DataToolsPrincipal.m
@@ -17,6 +17,7 @@
#import "DTConvertToDataPatch.h"
#import "DTConvertFromDataPatch.h"
#import "DTStringToDataPatch.h"
+#import "DTImageToDataPatch.h"
#import "SpookySendPatch.h"
#import "SpookyReceivePatch.h"
@@ -79,6 +80,7 @@ +(void)registerNodesWithManager:(QCNodeManager*)manager
KIRegisterPatch(DTConvertToDataPatch);
KIRegisterPatch(DTConvertFromDataPatch);
KIRegisterPatch(DTStringToDataPatch);
+ KIRegisterPatch(DTImageToDataPatch);
/* disabled for now, since this hack results in input splitters that require DataTools (which is kinda misleading)
{
diff --git a/TestDTConvert.m b/TestDTConvert.m
index bfbad6a..3f0be9b 100644
--- a/TestDTConvert.m
+++ b/TestDTConvert.m
@@ -2,6 +2,7 @@
#import "DTConvertToDataPatch.h"
#import "DTConvertFromDataPatch.h"
#import "DTStringToDataPatch.h"
+#import "DTImageToDataPatch.h"
@interface TestDTConvert : SkankySDK_TestCase
@@ -56,4 +57,34 @@ - (void)testStringToData
[dataString release];
}
+- (void)testImageToData
+{
+ DTImageToDataPatch *patch = [[DTImageToDataPatch alloc] initWithIdentifier:nil];
+
+ // TIFF image -> TIFF data
+ NSImage *compressedTiffNSImage = [[NSImage alloc] initWithContentsOfFile:@"/Library/User Pictures/Fun/Pizza.tif"];
+ NSData *inTiffData = [compressedTiffNSImage TIFFRepresentationUsingCompression:NSTIFFCompressionNone factor:0];
+ NSImage *inTiffNSImage = [[NSImage alloc] initWithData:inTiffData];
+ QCImage *inTiffQCImage = [[QCImage alloc] initWithNSImage:inTiffNSImage options:nil];
+ [self setInputValue:inTiffQCImage forPort:@"inputImage" onPatch:patch];
+ [self setInputValue:[NSNumber numberWithInt:NSTIFFFileType] forPort:@"inputImageFileType" onPatch:patch];
+ [self executePatch:patch];
+ NSData *outTiffData = [self getOutputForPort:@"outputRawData" onPatch:patch];
+ const unsigned char expectedTiffBytes[] = { 0x4d, 0x4d, 0x00, 0x2a };
+ NSData *expectedTiffData = [NSData dataWithBytes:(const void *)expectedTiffBytes length:4];
+ GHAssertEqualObjects(expectedTiffData, [outTiffData subdataWithRange:NSMakeRange(0, 4)], @"");
+// NSBitmapImageRep *outTiffImageRep = [NSBitmapImageRep imageRepWithData:outTiffData];
+// GHAssertEqualObjects(inTiffData, [outTiffImageRep TIFFRepresentation], @"");
+
+ // JPEG image -> PNG data
+ QCImage *inJpegQCImage = [[QCImage alloc] initWithFile:@"/Library/Desktop Pictures/Solid Colors/Solid Aqua Blue.png" options:nil];
+ [self setInputValue:inJpegQCImage forPort:@"inputImage" onPatch:patch];
+ [self setInputValue:[NSNumber numberWithInt:NSPNGFileType] forPort:@"inputImageFileType" onPatch:patch];
+ [self executePatch:patch];
+ NSData *outPngData = [self getOutputForPort:@"outputRawData" onPatch:patch];
+ const unsigned char expectedPngBytes[] = { 0x89, 0x50, 0x4e, 0x47 };
+ NSData *expectedPngData = [NSData dataWithBytes:(const void *)expectedPngBytes length:4];
+ GHAssertEqualObjects(expectedPngData, [outPngData subdataWithRange:NSMakeRange(0, 4)], @"");
+}
+
@end