// Copyright 2008 __MyCompanyName__. All rights reserved.
//
#import <QuickTime/QuickTime.h>
+#import <QuickTime/ImageCompression.h>
#import "TURAnsel.h"
#import "TURAnselGallery.h"
#import "AnselExportController.h"
#import "FBProgressController.h";
+#import "ImageResizer.h";
@interface AnselExportController (PrivateAPI)
- (void)connect;
// Prepare the image data
NSData *theImage = [[NSData alloc] initWithContentsOfFile: [mExportMgr imagePathAtIndex:i]];
- NSString *base64ImageData = [NSString base64StringFromData: theImage
- length: [theImage length]];
+
+ NSData *scaledData = [ImageResizer getScaledImageFromData: theImage
+ toSize: NSMakeSize(400, 400)];
+
+
+ NSString *base64ImageData = [NSString base64StringFromData: scaledData
+ length: [scaledData length]];
// Get the filename/path for this image. This returns either the most
// recent version of the image, the original, or (if RAW) the jpeg
--- /dev/null
+//
+// Copyright (c) Zach Wily
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// - Redistributions of source code must retain the above copyright notice, this
+// list of conditions and the following disclaimer.
+//
+// - Redistributions in binary form must reproduce the above copyright notice, this
+// list of conditions and the following disclaimer in the documentation and/or
+// other materials provided with the distribution.
+//
+// - Neither the name of Zach Wily nor the names of its contributors may be used to
+// endorse or promote products derived from this software without specific prior
+// written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+#import <Foundation/Foundation.h>
+
+@interface ImageResizer : NSObject {
+
+}
+
++ (NSData*) getScaledImageFromData:(NSData*)data toSize:(NSSize)size;
+
+@end
--- /dev/null
+//
+// Copyright (c) Zach Wily
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// - Redistributions of source code must retain the above copyright notice, this
+// list of conditions and the following disclaimer.
+//
+// - Redistributions in binary form must reproduce the above copyright notice, this
+// list of conditions and the following disclaimer in the documentation and/or
+// other materials provided with the distribution.
+//
+// - Neither the name of Zach Wily nor the names of its contributors may be used to
+// endorse or promote products derived from this software without specific prior
+// written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+#import "ImageResizer.h"
+#import "QuickTime/QuickTime.h"
+
+Handle myCreateHandleDataRef(
+ Handle dataHandle,
+ Str255 fileName,
+ OSType fileType,
+ StringPtr mimeTypeString,
+ Ptr initDataPtr,
+ Size initDataByteCount
+ );
+
+NSSize getGoodSize(NSSize size, NSSize maxSize);
+
+@implementation ImageResizer
+
++ (NSData*) getScaledImageFromData:(NSData*)data toSize:(NSSize)size {
+ NSData *scaledImageData;
+
+ Handle imageDataH = NULL;
+ PtrToHand([data bytes], &imageDataH, [data length]);
+ Handle dataRef = myCreateHandleDataRef(imageDataH, "\pdummy.jpg", kQTFileTypeJPEG, nil, nil, 0);
+
+ // create a Graphics Importer component that will read from the PNG data
+ ComponentInstance importComponent=0, exportComponent=0;
+ GetGraphicsImporterForDataRef(dataRef, HandleDataHandlerSubType, &importComponent); // TODO: check return value
+ DisposeHandle(dataRef);
+
+ // get metadata
+ UserData imageMetadata;
+ NewUserData(&imageMetadata);
+ GraphicsImportGetMetaData(importComponent, imageMetadata);
+ //GraphicsImportGetDescription(importComponent, &imageDescription);
+
+ Rect naturalBounds, scaledBounds;
+ GraphicsImportGetNaturalBounds(importComponent, &naturalBounds);
+
+ NSSize scaledSize = getGoodSize(NSMakeSize(naturalBounds.right, naturalBounds.bottom), size);
+
+ scaledBounds = naturalBounds;
+ scaledBounds.right = scaledSize.width;
+ scaledBounds.bottom = scaledSize.height;
+
+ GraphicsImportSetBoundsRect( importComponent, &scaledBounds );
+
+ // Now the exporter
+ OpenADefaultComponent(GraphicsExporterComponentType, kQTFileTypeJPEG, &exportComponent);
+
+ GraphicsExportSetInputGraphicsImporter(exportComponent, importComponent);
+
+ Handle scaledImageDataH = NewHandle(0);
+ GraphicsExportSetOutputHandle(exportComponent, scaledImageDataH);
+
+ GraphicsExportSetMetaData(exportComponent, imageMetadata);
+// GraphicsExportSetDescription(exportComponent, imageDescription);
+ GraphicsExportSetExifEnabled(exportComponent, TRUE);
+
+ unsigned long actualSizeWritten = 0;
+ GraphicsExportDoExport(exportComponent, &actualSizeWritten);
+ HLock(scaledImageDataH);
+ scaledImageData = [NSData dataWithBytes:*scaledImageDataH
+ length:GetHandleSize(scaledImageDataH)];
+ HUnlock(scaledImageDataH);
+
+ DisposeHandle(scaledImageDataH);
+ CloseComponent(exportComponent);
+ DisposeUserData(imageMetadata);
+ CloseComponent(importComponent);
+ DisposeHandle(imageDataH);
+
+ return scaledImageData;
+}
+
+NSSize getGoodSize(NSSize size, NSSize maxSize) {
+ int old_x = size.width;
+ int old_y = size.height;
+ int new_x = maxSize.width;
+ int new_y = maxSize.height;
+
+ // flip the Max dimensions if our source is taller than wide
+ if (old_y > old_x) {
+ new_x = maxSize.height;
+ new_y = maxSize.width;
+ }
+
+ int good_x;
+ int good_y;
+
+ float aspect = (float)old_x / (float)old_y;
+
+ if (aspect >= 1) {
+ good_x = new_x;
+ good_y = new_x / aspect;
+
+ if (good_y > new_y) {
+ good_y = new_y;
+ good_x = new_y * aspect;
+ }
+ }
+ else {
+ good_y = new_y;
+ good_x = aspect * new_y;
+
+ if (good_x > new_x) {
+ good_x = new_x;
+ good_y = new_x / aspect;
+ }
+ }
+ // Don't go any bigger!
+ if ((good_x > old_x) || (good_y > old_y)) {
+ good_x = old_x;
+ good_y = old_y;
+ }
+
+ return NSMakeSize(good_x, good_y);
+}
+
+Handle myCreateHandleDataRef(
+ Handle dataHandle,
+ Str255 fileName,
+ OSType fileType,
+ StringPtr mimeTypeString,
+ Ptr initDataPtr,
+ Size initDataByteCount
+ )
+{
+ OSErr err;
+ Handle dataRef = nil;
+ Str31 tempName;
+ long atoms[3];
+ StringPtr name;
+
+
+ // First create a data reference handle for our data
+ err = PtrToHand( &dataHandle, &dataRef, sizeof(Handle));
+ if (err) goto bail;
+
+ // If this is QuickTime 3 or later, we can add
+ // the filename to the data ref to help importer
+ // finding process. Find uses the extension.
+
+ name = fileName;
+ if (name == nil)
+ {
+ tempName[0] = 0;
+ name = tempName;
+ }
+
+ // Only add the file name if we are also adding a
+ // file type, MIME type or initialization data
+ if ((fileType) || (mimeTypeString) || (initDataPtr))
+ {
+ err = PtrAndHand(name, dataRef, name[0]+1);
+ if (err) goto bail;
+ }
+
+ // If this is QuickTime 4, the handle data handler
+ // can also be told the filetype and/or
+ // MIME type by adding data ref extensions. These
+ // help the importer finding process.
+ // NOTE: If you add either of these, you MUST add
+ // a filename first -- even if it is an empty Pascal
+ // string. Under QuickTime 3, any data ref extensions
+ // will be ignored.
+
+ // to add file type, you add a classic atom followed
+ // by the MacOS filetype for the kind of file
+
+ if (fileType)
+ {
+ atoms[0] = EndianU32_NtoB(sizeof(long) * 3);
+ atoms[1] = EndianU32_NtoB(kDataRefExtensionMacOSFileType);
+ atoms[2] = EndianU32_NtoB(fileType);
+
+ err = PtrAndHand(atoms, dataRef, sizeof(long) * 3);
+ if (err) goto bail;
+ }
+
+
+ // to add MIME type information, add a classic atom followed by
+ // a Pascal string holding the MIME type
+
+ if (mimeTypeString)
+ {
+ atoms[0] = EndianU32_NtoB(sizeof(long) * 2 + mimeTypeString[0]+1);
+ atoms[1] = EndianU32_NtoB(kDataRefExtensionMIMEType);
+
+ err = PtrAndHand(atoms, dataRef, sizeof(long) * 2);
+ if (err) goto bail;
+
+ err = PtrAndHand(mimeTypeString, dataRef, mimeTypeString[0]+1);
+ if (err) goto bail;
+ }
+
+ // add any initialization data, but only if a dataHandle was
+ // not already specified (any initialization data is ignored
+ // in this case)
+ if((dataHandle == nil) && (initDataPtr))
+ {
+
+ atoms[0] = EndianU32_NtoB(sizeof(long) * 2 + initDataByteCount);
+ atoms[1] = EndianU32_NtoB(kDataRefExtensionInitializationData);
+
+ err = PtrAndHand(atoms, dataRef, sizeof(long) * 2);
+ if (err) goto bail;
+
+ err = PtrAndHand(initDataPtr, dataRef, initDataByteCount);
+ if (err) goto bail;
+ }
+
+ return dataRef;
+
+bail:
+ if (dataRef)
+ {
+ // make sure and dispose the data reference handle
+ // once we are done with it
+ DisposeHandle(dataRef);
+ }
+
+ return nil;
+}
+
+
+@end
@end
@implementation TURAnsel
+
@synthesize rpcEndPoint;
@synthesize username;
@synthesize password;
+static NSString *ERR_DOMAIN = @"com.theupstairsroom.TURAnsel";
+
+
#pragma mark init
- (id)initWithConnectionParameters: (NSDictionary *)params
{
@property (readwrite) int galleryDefaultImage;
@property (readonly, retain) NSURL *galleryDefaultImageURL;
-- (id)initWithObject:(id)galleryData controller:(TURAnsel *)controller;
+- (id)initWithObject:(id)galleryData controller:(TURAnsel * )controller;
- (int)galleryId;
- (void)requestDefaultImageURL;
- (void)parseImageUrlRequest:(XMLRPCResponse *)response;
/* Begin PBXBuildFile section */
8D5B49B0048680CD000E48DA /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C167DFE841241C02AAC07 /* InfoPlist.strings */; };
8D5B49B4048680CD000E48DA /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */; };
+ B05C4A060EE9E001005B4B28 /* ImageResizer.m in Sources */ = {isa = PBXBuildFile; fileRef = B05C4A050EE9E001005B4B28 /* ImageResizer.m */; };
B06C1E030EB1644600BFAFCB /* AnselExportPluginBox.m in Sources */ = {isa = PBXBuildFile; fileRef = B06C1E020EB1644600BFAFCB /* AnselExportPluginBox.m */; };
B06C1E060EB164D900BFAFCB /* AnselExportController.m in Sources */ = {isa = PBXBuildFile; fileRef = B06C1E050EB164D900BFAFCB /* AnselExportController.m */; };
B06C1E3D0EB17E3700BFAFCB /* Panel.nib in Resources */ = {isa = PBXBuildFile; fileRef = B06C1E3C0EB17E3700BFAFCB /* Panel.nib */; };
B0BFBCAA0ED5B32B006581A5 /* XMLRPCResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = B0BFBC960ED5B32B006581A5 /* XMLRPCResponse.m */; };
B0C888490ED85DEA000E19FB /* ProgressSheet.nib in Resources */ = {isa = PBXBuildFile; fileRef = B0C888480ED85DEA000E19FB /* ProgressSheet.nib */; };
B0C8884E0ED85E02000E19FB /* FBProgressController.m in Sources */ = {isa = PBXBuildFile; fileRef = B0C8884D0ED85E02000E19FB /* FBProgressController.m */; };
+ B0DF843C0EE9E6EB000DAA9E /* QuickTime.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B0DF843B0EE9E6EB000DAA9E /* QuickTime.framework */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
/* Begin PBXFileReference section */
089C1672FE841209C02AAC07 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = "<absolute>"; };
089C167EFE841241C02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = "<group>"; };
- 089C167FFE841241C02AAC07 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = "<absolute>"; };
1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = "<absolute>"; };
32DBCF630370AF2F00C91783 /* iPhoto2Ansel_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = iPhoto2Ansel_Prefix.pch; sourceTree = "<group>"; };
8D5B49B6048680CD000E48DA /* iPhoto2Ansel.iPhotoExporter */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = iPhoto2Ansel.iPhotoExporter; sourceTree = BUILT_PRODUCTS_DIR; };
8D5B49B7048680CD000E48DA /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
B03D3B590ED5BB3800CF5B92 /* XMLRPC-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "XMLRPC-Info.plist"; sourceTree = SOURCE_ROOT; };
+ B05C4A040EE9E001005B4B28 /* ImageResizer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImageResizer.h; sourceTree = "<group>"; };
+ B05C4A050EE9E001005B4B28 /* ImageResizer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ImageResizer.m; sourceTree = "<group>"; };
B06C1E010EB1644600BFAFCB /* AnselExportPluginBox.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AnselExportPluginBox.h; sourceTree = "<group>"; };
B06C1E020EB1644600BFAFCB /* AnselExportPluginBox.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AnselExportPluginBox.m; sourceTree = "<group>"; };
B06C1E040EB164D900BFAFCB /* AnselExportController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AnselExportController.h; sourceTree = "<group>"; };
B0C888480ED85DEA000E19FB /* ProgressSheet.nib */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; path = ProgressSheet.nib; sourceTree = "<group>"; };
B0C8884C0ED85E02000E19FB /* FBProgressController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBProgressController.h; sourceTree = "<group>"; };
B0C8884D0ED85E02000E19FB /* FBProgressController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBProgressController.m; sourceTree = "<group>"; };
- D2F7E65807B2D6F200F64583 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = /System/Library/Frameworks/CoreData.framework; sourceTree = "<absolute>"; };
+ B0DF843B0EE9E6EB000DAA9E /* QuickTime.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuickTime.framework; path = /System/Library/Frameworks/QuickTime.framework; sourceTree = "<absolute>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
files = (
B0BFBC780ED5B2AB006581A5 /* XMLRPC.framework in Frameworks */,
8D5B49B4048680CD000E48DA /* Cocoa.framework in Frameworks */,
+ B0DF843C0EE9E6EB000DAA9E /* QuickTime.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
1058C7ACFEA557BF11CA2CBB /* Linked Frameworks */ = {
isa = PBXGroup;
children = (
+ B0DF843B0EE9E6EB000DAA9E /* QuickTime.framework */,
+ 089C1672FE841209C02AAC07 /* Foundation.framework */,
1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */,
);
name = "Linked Frameworks";
1058C7AEFEA557BF11CA2CBB /* Other Frameworks */ = {
isa = PBXGroup;
children = (
- 089C167FFE841241C02AAC07 /* AppKit.framework */,
- D2F7E65807B2D6F200F64583 /* CoreData.framework */,
- 089C1672FE841209C02AAC07 /* Foundation.framework */,
);
name = "Other Frameworks";
sourceTree = "<group>";
32C88E010371C26100C91783 /* Other Sources */ = {
isa = PBXGroup;
children = (
+ B05C4A040EE9E001005B4B28 /* ImageResizer.h */,
+ B05C4A050EE9E001005B4B28 /* ImageResizer.m */,
B0C8884D0ED85E02000E19FB /* FBProgressController.m */,
B0C8884C0ED85E02000E19FB /* FBProgressController.h */,
B07D44F50EC2AEC700B59765 /* TURXMLConnection.h */,
B07D42710EC230B100B59765 /* TURAnselGallery.m in Sources */,
B07D44F70EC2AEC700B59765 /* TURXMLConnection.m in Sources */,
B0C8884E0ED85E02000E19FB /* FBProgressController.m in Sources */,
+ B05C4A060EE9E001005B4B28 /* ImageResizer.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
--- /dev/null
+//
+// Copyright (c) Zach Wily
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// - Redistributions of source code must retain the above copyright notice, this
+// list of conditions and the following disclaimer.
+//
+// - Redistributions in binary form must reproduce the above copyright notice, this
+// list of conditions and the following disclaimer in the documentation and/or
+// other materials provided with the distribution.
+//
+// - Neither the name of Zach Wily nor the names of its contributors may be used to
+// endorse or promote products derived from this software without specific prior
+// written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+#import <Foundation/Foundation.h>
+
+@interface ImageResizer : NSObject {
+
+}
+
++ (NSData*) getScaledImageFromData:(NSData*)data toSize:(NSSize)size;
+
+@end