mirror of
https://github.com/arsenetar/dupeguru.git
synced 2026-01-22 14:41:39 +00:00
Converted PictureBlocks to a Python extension and created a "common" C unit for common code among extensions.
This commit is contained in:
@@ -1,19 +0,0 @@
|
||||
/*
|
||||
Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
||||
|
||||
This software is licensed under the "HS" License as described in the "LICENSE" file,
|
||||
which should be included with this package. The terms are also available at
|
||||
http://www.hardcoded.net/licenses/hs_license
|
||||
*/
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
|
||||
@interface PictureBlocks : NSObject {
|
||||
}
|
||||
+ (NSString *)getBlocksFromImagePath:(NSString *)imagePath blockCount:(NSNumber *)blockCount;
|
||||
+ (NSSize)getImageSize:(NSString *)imagePath;
|
||||
@end
|
||||
|
||||
|
||||
NSString* GetBlocks(NSString *filePath, int blockCount);
|
||||
@@ -1,146 +0,0 @@
|
||||
/*
|
||||
Copyright 2010 Hardcoded Software (http://www.hardcoded.net)
|
||||
|
||||
This software is licensed under the "HS" License as described in the "LICENSE" file,
|
||||
which should be included with this package. The terms are also available at
|
||||
http://www.hardcoded.net/licenses/hs_license
|
||||
*/
|
||||
|
||||
#import "PictureBlocks.h"
|
||||
#import "Utils.h"
|
||||
|
||||
@implementation PictureBlocks
|
||||
+ (NSString *)getBlocksFromImagePath:(NSString *)imagePath blockCount:(NSNumber *)blockCount
|
||||
{
|
||||
return GetBlocks(imagePath, n2i(blockCount));
|
||||
}
|
||||
|
||||
+ (NSSize)getImageSize:(NSString *)imagePath
|
||||
{
|
||||
CFURLRef fileURL = CFURLCreateWithFileSystemPath(NULL, (CFStringRef)imagePath, kCFURLPOSIXPathStyle, FALSE);
|
||||
CGImageSourceRef source = CGImageSourceCreateWithURL(fileURL, NULL);
|
||||
if (source == NULL)
|
||||
return NSMakeSize(0, 0);
|
||||
CGImageRef image = CGImageSourceCreateImageAtIndex(source, 0, NULL);
|
||||
if (image == NULL)
|
||||
return NSMakeSize(0, 0);
|
||||
size_t width = CGImageGetWidth(image);
|
||||
size_t height = CGImageGetHeight(image);
|
||||
CGImageRelease(image);
|
||||
CFRelease(source);
|
||||
CFRelease(fileURL);
|
||||
return NSMakeSize(width, height);
|
||||
}
|
||||
@end
|
||||
|
||||
CGContextRef MyCreateBitmapContext (int width, int height)
|
||||
{
|
||||
CGContextRef context = NULL;
|
||||
CGColorSpaceRef colorSpace;
|
||||
void * bitmapData;
|
||||
int bitmapByteCount;
|
||||
int bitmapBytesPerRow;
|
||||
|
||||
bitmapBytesPerRow = (width * 4);
|
||||
bitmapByteCount = (bitmapBytesPerRow * height);
|
||||
|
||||
colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
|
||||
|
||||
// calloc() must be used to allocate bitmapData here because the buffer has to be zeroed.
|
||||
// If it's not zeroes, when images with transparency are drawn in the context, this buffer
|
||||
// will stay with undefined pixels, which means that two pictures with the same pixels will
|
||||
// most likely have different blocks (which is not supposed to happen).
|
||||
bitmapData = calloc(bitmapByteCount, 1);
|
||||
if (bitmapData == NULL)
|
||||
{
|
||||
fprintf (stderr, "Memory not allocated!");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
context = CGBitmapContextCreate (bitmapData,width,height,8,bitmapBytesPerRow,colorSpace,kCGImageAlphaNoneSkipLast);
|
||||
if (context== NULL)
|
||||
{
|
||||
free (bitmapData);
|
||||
fprintf (stderr, "Context not created!");
|
||||
return NULL;
|
||||
}
|
||||
CGColorSpaceRelease( colorSpace );
|
||||
return context;
|
||||
}
|
||||
|
||||
// returns 0x00RRGGBB
|
||||
int GetBlock(unsigned char *imageData, int imageWidth, int imageHeight, int boxX, int boxY, int boxW, int boxH)
|
||||
{
|
||||
int i,j;
|
||||
int totalR = 0;
|
||||
int totalG = 0;
|
||||
int totalB = 0;
|
||||
for(i = boxY; i < boxY + boxH; i++)
|
||||
{
|
||||
for(j = boxX; j < boxX + boxW; j++)
|
||||
{
|
||||
int offset = (i * imageWidth * 4) + (j * 4);
|
||||
totalR += *(imageData + offset);
|
||||
totalG += *(imageData + offset + 1);
|
||||
totalB += *(imageData + offset + 2);
|
||||
}
|
||||
}
|
||||
int pixelCount = boxH * boxW;
|
||||
int result = 0;
|
||||
result += (totalR / pixelCount) << 16;
|
||||
result += (totalG / pixelCount) << 8;
|
||||
result += (totalB / pixelCount);
|
||||
return result;
|
||||
}
|
||||
|
||||
NSString* GetBlocks (NSString* filePath, int blockCount)
|
||||
{
|
||||
CFURLRef fileURL = CFURLCreateWithFileSystemPath(NULL, (CFStringRef)filePath, kCFURLPOSIXPathStyle, FALSE);
|
||||
CGImageSourceRef source = CGImageSourceCreateWithURL(fileURL, NULL);
|
||||
if (source == NULL)
|
||||
return NULL;
|
||||
CGImageRef image = CGImageSourceCreateImageAtIndex(source, 0, NULL);
|
||||
if (image == NULL)
|
||||
return NULL;
|
||||
size_t width = CGImageGetWidth(image);
|
||||
size_t height = CGImageGetHeight(image);
|
||||
CGContextRef myContext = MyCreateBitmapContext(width, height);
|
||||
CGRect myBoundingBox = CGRectMake (0, 0, width, height);
|
||||
CGContextDrawImage(myContext, myBoundingBox, image);
|
||||
unsigned char *bitmapData = CGBitmapContextGetData(myContext);
|
||||
if (bitmapData == NULL)
|
||||
return NULL;
|
||||
|
||||
int blockHeight = height / blockCount;
|
||||
if (blockHeight < 1)
|
||||
blockHeight = 1;
|
||||
int blockWidth = width / blockCount;
|
||||
if (blockWidth < 1)
|
||||
blockWidth = 1;
|
||||
//blockCount might have changed
|
||||
int blockXCount = (width / blockWidth);
|
||||
int blockYCount = (height / blockHeight);
|
||||
|
||||
CFMutableArrayRef blocks = CFArrayCreateMutable(NULL, blockXCount * blockYCount, &kCFTypeArrayCallBacks);
|
||||
int i,j;
|
||||
for(i = 0; i < blockYCount; i++)
|
||||
{
|
||||
for(j = 0; j < blockXCount; j++)
|
||||
{
|
||||
int block = GetBlock(bitmapData, width, height, j * blockWidth, i * blockHeight, blockWidth, blockHeight);
|
||||
CFStringRef strBlock = CFStringCreateWithFormat(NULL, NULL, CFSTR("%06x"), block);
|
||||
CFArrayAppendValue(blocks, strBlock);
|
||||
CFRelease(strBlock);
|
||||
}
|
||||
}
|
||||
|
||||
CGContextRelease (myContext);
|
||||
if (bitmapData) free(bitmapData);
|
||||
CGImageRelease(image);
|
||||
CFRelease(source);
|
||||
CFRelease(fileURL);
|
||||
|
||||
CFStringRef result = CFStringCreateByCombiningStrings(NULL, blocks, CFSTR(""));
|
||||
CFRelease(blocks);
|
||||
return (NSString *)result;
|
||||
}
|
||||
@@ -12,7 +12,6 @@
|
||||
CE031751109B340A00517EE6 /* Preferences.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE031750109B340A00517EE6 /* Preferences.xib */; };
|
||||
CE031754109B345200517EE6 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE031753109B345200517EE6 /* MainMenu.xib */; };
|
||||
CE073F6309CAE1A3005C1D2F /* dupeguru_pe_help in Resources */ = {isa = PBXBuildFile; fileRef = CE073F5409CAE1A3005C1D2F /* dupeguru_pe_help */; };
|
||||
CE0C46AA0FA0647E000BE99B /* PictureBlocks.m in Sources */ = {isa = PBXBuildFile; fileRef = CE0C46A90FA0647E000BE99B /* PictureBlocks.m */; };
|
||||
CE15C8A80ADEB8B50061D4A5 /* Sparkle.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CE15C8A70ADEB8B50061D4A5 /* Sparkle.framework */; };
|
||||
CE15C8C00ADEB8D40061D4A5 /* Sparkle.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = CE15C8A70ADEB8B50061D4A5 /* Sparkle.framework */; };
|
||||
CE381C9609914ACE003581CE /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = CE381C9409914ACE003581CE /* AppDelegate.m */; };
|
||||
@@ -77,8 +76,6 @@
|
||||
CE031750109B340A00517EE6 /* Preferences.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = Preferences.xib; sourceTree = "<group>"; };
|
||||
CE031753109B345200517EE6 /* MainMenu.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = MainMenu.xib; path = ../../base/xib/MainMenu.xib; sourceTree = "<group>"; };
|
||||
CE073F5409CAE1A3005C1D2F /* dupeguru_pe_help */ = {isa = PBXFileReference; lastKnownFileType = folder; name = dupeguru_pe_help; path = ../../help_pe/dupeguru_pe_help; sourceTree = SOURCE_ROOT; };
|
||||
CE0C46A80FA0647E000BE99B /* PictureBlocks.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PictureBlocks.h; sourceTree = "<group>"; };
|
||||
CE0C46A90FA0647E000BE99B /* PictureBlocks.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PictureBlocks.m; sourceTree = "<group>"; };
|
||||
CE15C8A70ADEB8B50061D4A5 /* Sparkle.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Sparkle.framework; path = /Library/Frameworks/Sparkle.framework; sourceTree = "<absolute>"; };
|
||||
CE381C9409914ACE003581CE /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = SOURCE_ROOT; };
|
||||
CE381C9509914ACE003581CE /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = SOURCE_ROOT; };
|
||||
@@ -155,8 +152,6 @@
|
||||
080E96DDFE201D6D7F000001 /* Classes */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
CE0C46A80FA0647E000BE99B /* PictureBlocks.h */,
|
||||
CE0C46A90FA0647E000BE99B /* PictureBlocks.m */,
|
||||
CE381C9509914ACE003581CE /* AppDelegate.h */,
|
||||
CE381C9409914ACE003581CE /* AppDelegate.m */,
|
||||
CE848A1809DD85810004CB44 /* Consts.h */,
|
||||
@@ -409,7 +404,6 @@
|
||||
CE381C9C09914ADF003581CE /* ResultWindow.m in Sources */,
|
||||
CE68EE6809ABC48000971085 /* DirectoryPanel.m in Sources */,
|
||||
CECA899D09DB132E00A3D774 /* DetailsPanel.m in Sources */,
|
||||
CE0C46AA0FA0647E000BE99B /* PictureBlocks.m in Sources */,
|
||||
CE80DB2E0FC192D60086DCA6 /* Dialogs.m in Sources */,
|
||||
CE80DB2F0FC192D60086DCA6 /* HSErrorReportWindow.m in Sources */,
|
||||
CE80DB300FC192D60086DCA6 /* Outline.m in Sources */,
|
||||
|
||||
Reference in New Issue
Block a user