Permalink
Browse files

Added 'Image To Data' patch to convert an image to bytes. [#2170]

  • Loading branch information...
1 parent b3be0cb commit 2d99dd88d9fd8c6189eab9ad77373f54a429c904 @jlstrecker jlstrecker committed May 1, 2012
Showing with 170 additions and 2 deletions.
  1. +15 −0 DTImageToDataPatch.h
  2. +53 −0 DTImageToDataPatch.m
  3. +57 −0 DTImageToDataPatch.xml
  4. +12 −2 DataTools.xcodeproj/project.pbxproj
  5. +2 −0 DataToolsPrincipal.m
  6. +31 −0 TestDTConvert.m
View
@@ -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
View
@@ -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
View
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>nodeAttributes</key>
+ <dict>
+ <key>name</key>
+ <string>Image To Data</string>
+ <key>categories</key>
+ <array>
+ <string>Kineme DataTools</string>
+ </array>
+ <key>copyright</key>
+ <string>Copyright 2011 Kosada Incorporated. All rights reserved.</string>
+ <key>description</key>
+ <string>This patch converts an image to raw data bytes.
+
+http://kineme.net/</string>
+ </dict>
+ <key>inputAttributes</key>
+ <dict>
+ <key>inputImage</key>
+ <dict>
+ <key>name</key>
+ <string>Image</string>
+ <key>description</key>
+ <string>The image to convert</string>
+ </dict>
+ <key>inputImageFileType</key>
+ <dict>
+ <key>name</key>
+ <string>Image Representation</string>
+ <key>description</key>
+ <string>The image representation to use when converting to bytes</string>
+ <key>menu</key>
+ <array>
+ <string>TIFF</string>
+ <string>BMP</string>
+ <string>GIF</string>
+ <string>JPEG</string>
+ <string>PNG</string>
+ <string>JPEG2000</string>
+ </array>
+ </dict>
+ </dict>
+ <key>outputAttributes</key>
+ <dict>
+ <key>outputRawData</key>
+ <dict>
+ <key>name</key>
+ <string>Raw Data</string>
+ <key>description</key>
+ <string>The bytes of the image</string>
+ </dict>
+ </dict>
+</dict>
+</plist>
@@ -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 = "<group>"; };
E74FE09F15502957009E29D6 /* DTStringToDataPatch.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DTStringToDataPatch.m; sourceTree = "<group>"; };
E74FE0CA15502E3F009E29D6 /* DTStringToDataPatch.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = DTStringToDataPatch.xml; sourceTree = "<group>"; };
+ E74FE11D15505A7F009E29D6 /* DTImageToDataPatch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DTImageToDataPatch.h; sourceTree = "<group>"; };
+ E74FE11E15505A7F009E29D6 /* DTImageToDataPatch.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DTImageToDataPatch.m; sourceTree = "<group>"; };
+ E74FE12115505A8D009E29D6 /* DTImageToDataPatch.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = DTImageToDataPatch.xml; sourceTree = "<group>"; };
E78586E713E9F64A000BBF4B /* DTStructureKeyPatch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DTStructureKeyPatch.h; sourceTree = "<group>"; };
E78586E813E9F64A000BBF4B /* DTStructureKeyPatch.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DTStructureKeyPatch.m; sourceTree = "<group>"; };
E78586EA13E9F7DB000BBF4B /* DTStructureKeyPatch.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = DTStructureKeyPatch.xml; sourceTree = "<group>"; };
@@ -371,6 +377,7 @@
E7DC1662134E13A700DBDFC8 /* DTConvertToDataPatch.xml */,
E7DC1664134E13E600DBDFC8 /* DTConvertFromDataPatch.xml */,
E74FE0CA15502E3F009E29D6 /* DTStringToDataPatch.xml */,
+ E74FE12115505A8D009E29D6 /* DTImageToDataPatch.xml */,
);
name = XML;
sourceTree = "<group>";
@@ -467,6 +474,8 @@
E7DC1621134E0F9E00DBDFC8 /* DTConvertFromDataPatch.m */,
E74FE09E15502957009E29D6 /* DTStringToDataPatch.h */,
E74FE09F15502957009E29D6 /* DTStringToDataPatch.m */,
+ E74FE11D15505A7F009E29D6 /* DTImageToDataPatch.h */,
+ E74FE11E15505A7F009E29D6 /* DTImageToDataPatch.m */,
);
name = Convert;
sourceTree = "<group>";
@@ -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;
};
View
@@ -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)
{
View
@@ -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

0 comments on commit 2d99dd8

Please sign in to comment.