Skip to content

Commit

Permalink
try to fix fading images?
Browse files Browse the repository at this point in the history
OS X changed default colorspace settings for reading images it seems
  • Loading branch information
alexzielenski committed Dec 31, 2018
1 parent 5411d09 commit b570903
Show file tree
Hide file tree
Showing 8 changed files with 97 additions and 41 deletions.
8 changes: 8 additions & 0 deletions Mousecape/Mousecape.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@
FAAEF951189F0CC300145DF8 /* restore.m in Sources */ = {isa = PBXBuildFile; fileRef = FA8FF76A189D664400750E51 /* restore.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
FAAEF957189F4ED300145DF8 /* scale.m in Sources */ = {isa = PBXBuildFile; fileRef = FAAEF956189F4ED300145DF8 /* scale.m */; };
FAAEF958189F4F8200145DF8 /* scale.m in Sources */ = {isa = PBXBuildFile; fileRef = FAAEF956189F4ED300145DF8 /* scale.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
FABA44D421D9D7D0009B10D9 /* NSBitmapImageRep+ColorSpace.m in Sources */ = {isa = PBXBuildFile; fileRef = FABA44D321D9D7D0009B10D9 /* NSBitmapImageRep+ColorSpace.m */; };
FABA44D521D9D947009B10D9 /* NSBitmapImageRep+ColorSpace.m in Sources */ = {isa = PBXBuildFile; fileRef = FABA44D321D9D7D0009B10D9 /* NSBitmapImageRep+ColorSpace.m */; };
FAC69F65189D603C00BC829D /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FAC69F64189D603C00BC829D /* Cocoa.framework */; };
FAC69F6F189D603C00BC829D /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = FAC69F6D189D603C00BC829D /* InfoPlist.strings */; };
FAC69F71189D603C00BC829D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = FAC69F70189D603C00BC829D /* main.m */; };
Expand Down Expand Up @@ -223,6 +225,8 @@
FAAEF8F6189EB34700145DF8 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
FAAEF955189F4ECC00145DF8 /* scale.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = scale.h; sourceTree = "<group>"; };
FAAEF956189F4ED300145DF8 /* scale.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = scale.m; sourceTree = "<group>"; };
FABA44D221D9D7D0009B10D9 /* NSBitmapImageRep+ColorSpace.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSBitmapImageRep+ColorSpace.h"; sourceTree = "<group>"; };
FABA44D321D9D7D0009B10D9 /* NSBitmapImageRep+ColorSpace.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "NSBitmapImageRep+ColorSpace.m"; sourceTree = "<group>"; };
FAC69F61189D603C00BC829D /* Mousecape.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Mousecape.app; sourceTree = BUILT_PRODUCTS_DIR; };
FAC69F64189D603C00BC829D /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; };
FAC69F67189D603C00BC829D /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; };
Expand Down Expand Up @@ -508,6 +512,8 @@
FAC69FCB189D609B00BC829D /* NSCursor_Private.h */,
FAC69FB4189D608900BC829D /* mousecloak.1 */,
FAC69FB2189D608900BC829D /* Supporting Files */,
FABA44D221D9D7D0009B10D9 /* NSBitmapImageRep+ColorSpace.h */,
FABA44D321D9D7D0009B10D9 /* NSBitmapImageRep+ColorSpace.m */,
);
path = mousecloak;
sourceTree = "<group>";
Expand Down Expand Up @@ -905,6 +911,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
FABA44D521D9D947009B10D9 /* NSBitmapImageRep+ColorSpace.m in Sources */,
FAEE653018A047E8003AA182 /* MCLibraryViewController.m in Sources */,
FAEE653618A047E8003AA182 /* MMAnimatingImageView.m in Sources */,
FAEE653318A047E8003AA182 /* MCCursorLibrary.m in Sources */,
Expand Down Expand Up @@ -957,6 +964,7 @@
FAC69FDD189D636700BC829D /* MCDefs.m in Sources */,
FAC69FD4189D609B00BC829D /* GBCommandLineParser.m in Sources */,
FA8FF774189D67B100750E51 /* create.m in Sources */,
FABA44D421D9D7D0009B10D9 /* NSBitmapImageRep+ColorSpace.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
2 changes: 1 addition & 1 deletion Mousecape/Mousecape/Mousecape-Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1618</string>
<string>1633</string>
<key>LSApplicationCategoryType</key>
<string>public.app-category.utilities</string>
<key>LSMinimumSystemVersion</key>
Expand Down
26 changes: 13 additions & 13 deletions Mousecape/Mousecape/src/models/MCCursor.m
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
//

#import "MCCursor.h"

#import "NSBitmapImageRep+ColorSpace.h"
MCCursorScale cursorScaleForScale(CGFloat scale) {
if (scale < 0.0)
return MCCursorScaleNone;
Expand All @@ -16,7 +16,7 @@ MCCursorScale cursorScaleForScale(CGFloat scale) {
}

@interface MCCursor ()
@property (readwrite, strong) NSMutableDictionary *representations;
@property (readwrite, strong) NSMutableDictionary<NSString *, NSBitmapImageRep *> *representations;
- (NSInteger)framesForScale:(MCCursorScale)scale;
- (BOOL)_readFromDictionary:(NSDictionary *)dictionary ofVersion:(CGFloat)version;
@end
Expand Down Expand Up @@ -105,7 +105,7 @@ - (BOOL)_readFromDictionary:(NSDictionary *)dictionary ofVersion:(CGFloat)versio
// data in v2.0 documents are saved as PNGs
NSBitmapImageRep *rep = [[NSBitmapImageRep alloc] initWithData:data];
rep.size = NSMakeSize(self.size.width, self.size.height * self.frameCount);
[self setRepresentation:rep forScale:cursorScaleForScale(rep.pixelsWide / self.size.width)];
[self setRepresentation:rep.ensuredSRGBSpace forScale:cursorScaleForScale(rep.pixelsWide / self.size.width)];
}

return YES;
Expand All @@ -127,7 +127,7 @@ - (NSDictionary *)dictionaryRepresentation {
NSMutableArray *pngs = [NSMutableArray array];
for (NSString *key in self.representations) {
NSBitmapImageRep *rep = self.representations[key];
pngs[pngs.count] = [rep representationUsingType:NSPNGFileType properties:nil];
pngs[pngs.count] = [rep representationUsingType:NSPNGFileType properties:@{}];
}

drep[MCCursorDictionaryRepresentationsKey] = pngs;
Expand Down Expand Up @@ -177,15 +177,15 @@ - (void)setValue:(id)value forUndefinedKey:(NSString *)key {
[super setValue:value forUndefinedKey:key];
}

- (void)setRepresentation:(NSImageRep *)imageRep forScale:(MCCursorScale)scale {
- (void)setRepresentation:(NSBitmapImageRep *)imageRep forScale:(MCCursorScale)scale {
[self willChangeValueForKey:@"representations"];

NSString *key = [@"cursorRep" stringByAppendingFormat:@"%lu", scale];
[self willChangeValueForKey:key];
if (imageRep)
[self.representations setObject:imageRep forKey:@(scale)];
else
[self.representations removeObjectForKey:@(scale)];
[self.representations removeObjectForKey:[NSString stringWithFormat:@"%lu", (unsigned long)scale, nil]];

if (self.representations.count == 1) {
// This is the first object, set the image size to this
Expand All @@ -212,7 +212,7 @@ - (void)addFrame:(NSImageRep *)frame forScale:(MCCursorScale)scale {
[self setRepresentation:newRep forScale:scale];
}

+ (NSImageRep *)composeRepresentationWithFrames:(NSArray *)frames {
+ (NSBitmapImageRep *)composeRepresentationWithFrames:(NSArray<NSBitmapImageRep *> *)frames {
if (frames.count == 0)
return nil;
if (frames.count == 1)
Expand All @@ -228,7 +228,7 @@ + (NSImageRep *)composeRepresentationWithFrames:(NSArray *)frames {
samplesPerPixel:4
hasAlpha:YES
isPlanar:NO
colorSpaceName:NSDeviceRGBColorSpace
colorSpaceName:NSCalibratedRGBColorSpace
bytesPerRow:4 * width
bitsPerPixel:32];
NSGraphicsContext *ctx = [NSGraphicsContext graphicsContextWithBitmapImageRep:newRep];
Expand All @@ -237,15 +237,15 @@ + (NSImageRep *)composeRepresentationWithFrames:(NSArray *)frames {

NSUInteger currentY = 0;
for (NSInteger idx = frames.count - 1; idx >= 0; idx--) {
NSImageRep *rep = frames[idx];
NSBitmapImageRep *rep = frames[idx];
if (rep.pixelsWide != width) {
NSLog(@"Can't create representation from images of different widths");
return nil;
}

[rep drawInRect:NSMakeRect(0, currentY, rep.pixelsWide, rep.pixelsHigh)
fromRect:NSZeroRect
operation:NSCompositeSourceOver
operation:NSCompositingOperationSourceOver
fraction:1.0
respectFlipped:YES
hints:nil];
Expand All @@ -255,7 +255,7 @@ + (NSImageRep *)composeRepresentationWithFrames:(NSArray *)frames {

[NSGraphicsContext restoreGraphicsState];

return newRep;
return [newRep ensuredSRGBSpace];
}

- (NSInteger)framesForScale:(MCCursorScale)scale {
Expand All @@ -267,7 +267,7 @@ - (void)removeRepresentationForScale:(MCCursorScale)scale {
}

- (NSImageRep *)representationForScale:(MCCursorScale)scale {
return self.representations[@(scale)];
return self.representations[[NSString stringWithFormat:@"%lu", (unsigned long)scale, nil]];
}

- (NSImageRep *)representationWithScale:(CGFloat)scale {
Expand Down
2 changes: 1 addition & 1 deletion Mousecape/Mousecape/src/views/MMAnimatingImageView.m
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,7 @@ - (void)pasteboard:(NSPasteboard *)sender item:(NSPasteboardItem *)item provideD
if ([rep isKindOfClass:[NSBitmapImageRep class]]) {
[sender setData:[(NSBitmapImageRep *)rep representationUsingType:NSPNGFileType properties:@{}] forType:NSPasteboardTypePNG];
} else {
abort();
// abort();
}
} else if ([type compare:@"public.image"] == NSOrderedSame) {
[sender writeObjects:@[ self.image ]];
Expand Down
19 changes: 19 additions & 0 deletions Mousecape/mousecloak/NSBitmapImageRep+ColorSpace.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//
// NSBitmapImageRep+ColorSpace.h
// mousecloak
//
// Created by Alexander Zielenski on 12/30/18.
// Copyright © 2018 Alex Zielenski. All rights reserved.
//

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface NSBitmapImageRep (ColorSpace)

- (NSBitmapImageRep *)ensuredSRGBSpace;
- (CGImageRef)copyEnsuredCGImage;
@end

NS_ASSUME_NONNULL_END
33 changes: 33 additions & 0 deletions Mousecape/mousecloak/NSBitmapImageRep+ColorSpace.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
//
// NSBitmapImageRep+ColorSpace.m
// mousecloak
//
// Created by Alexander Zielenski on 12/30/18.
// Copyright © 2018 Alex Zielenski. All rights reserved.
//

#import "NSBitmapImageRep+ColorSpace.h"

@implementation NSBitmapImageRep (ColorSpace)
- (NSBitmapImageRep *)ensuredSRGBSpace {
NSColorSpace *targetSpace = [NSColorSpace sRGBColorSpace];
if (self.colorSpace != NULL) {
if (self.colorSpace.numberOfColorComponents == 1) {
targetSpace = [NSColorSpace genericGamma22GrayColorSpace];
}
}
return [self bitmapImageRepByRetaggingWithColorSpace:targetSpace];
}
- (CGImageRef)copyEnsuredCGImage {
CGImageRef ref = self.ensuredSRGBSpace.CGImage;
CGColorSpaceRef space = CGImageGetColorSpace(ref);
NSColorSpace *targetSpace = [NSColorSpace sRGBColorSpace];
if (space != NULL) {
if (CGColorSpaceGetNumberOfComponents(space) == 1) {
targetSpace = [NSColorSpace genericGamma22GrayColorSpace];
}
}

return CGImageCreateCopyWithColorSpace(ref, space);
}
@end
33 changes: 13 additions & 20 deletions Mousecape/mousecloak/apply.m
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#import "backup.h"
#import "restore.h"
#import "MCPrefs.h"
#import "NSBitmapImageRep+ColorSpace.h"

BOOL applyCursorForIdentifier(NSUInteger frameCount, CGFloat frameDuration, CGPoint hotSpot, CGSize size, NSArray *images, NSString *ident, NSUInteger repeatCount) {
if (frameCount > 24 || frameCount < 1) {
Expand Down Expand Up @@ -61,38 +62,30 @@ BOOL applyCapeForIdentifier(NSDictionary *cursor, NSString *identifier, BOOL res

for (id object in reps) {
CFTypeID type = CFGetTypeID((__bridge CFTypeRef)object);

NSBitmapImageRep *rep;
if (type == CGImageGetTypeID()) {
rep = [[NSBitmapImageRep alloc] initWithCGImage:(__bridge CGImageRef)object];
} else {
rep = [[NSBitmapImageRep alloc] initWithData:object];
}
if (!lefty || restore || !pointer) {
// special case if array has a type of CGImage already there is no need to convert it
if (type == CGImageGetTypeID()) {
images[images.count] = object;
continue;
}

CFDataRef pngData = (__bridge CFDataRef)object;
CGDataProviderRef pngProvider = CGDataProviderCreateWithCFData(pngData);
CGImageRef rep = CGImageCreateWithPNGDataProvider(pngProvider, NULL, false, kCGRenderingIntentDefault);
CGDataProviderRelease(pngProvider);

images[images.count] = (__bridge id)rep;

CGImageRelease(rep);

images[images.count] = (__bridge id)[rep.ensuredSRGBSpace CGImage];

} else {
NSBitmapImageRep *rep;
if (type == CGImageGetTypeID()) {
rep = [[NSBitmapImageRep alloc] initWithCGImage:(__bridge CGImageRef)object];
} else {
rep = [[NSBitmapImageRep alloc] initWithData:object];
}

NSBitmapImageRep *newRep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL
pixelsWide:rep.pixelsWide
pixelsHigh:rep.pixelsHigh
bitsPerSample:8
samplesPerPixel:4
hasAlpha:YES
isPlanar:NO
colorSpaceName:NSDeviceRGBColorSpace
colorSpaceName:NSCalibratedRGBColorSpace
bytesPerRow:4 * rep.pixelsWide
bitsPerPixel:32];
NSGraphicsContext *ctx = [NSGraphicsContext graphicsContextWithBitmapImageRep:newRep];
Expand All @@ -105,12 +98,12 @@ BOOL applyCapeForIdentifier(NSDictionary *cursor, NSString *identifier, BOOL res

[rep drawInRect:NSMakeRect(0, 0, rep.pixelsWide, rep.pixelsHigh)
fromRect:NSZeroRect
operation:NSCompositeSourceOver
operation:NSCompositingOperationSourceOver
fraction:1.0
respectFlipped:NO
hints:nil];
[NSGraphicsContext restoreGraphicsState];
images[images.count] = (__bridge id)[newRep CGImage];
images[images.count] = (__bridge id)[newRep.ensuredSRGBSpace CGImage];
}
}

Expand Down
15 changes: 9 additions & 6 deletions Mousecape/mousecloak/create.m
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

#import "create.h"
#import "NSCursor_Private.h"
#import "NSBitmapImageRep+ColorSpace.h"

NSError *createCape(NSString *input, NSString *output, BOOL convert) {
NSDictionary *cape;
Expand Down Expand Up @@ -111,9 +112,8 @@
continue;

NSBitmapImageRep *image = [NSBitmapImageRep imageRepWithData:[NSData dataWithContentsOfFile:repPath]];

if (image) {
NSData *pngData = [image representationUsingType:NSPNGFileType properties:nil];
NSData *pngData = [image.ensuredSRGBSpace representationUsingType:NSPNGFileType properties:@{}];
[representations addObject:pngData];
}

Expand Down Expand Up @@ -186,12 +186,12 @@
samplesPerPixel:spp.integerValue
hasAlpha:YES
isPlanar:NO
colorSpaceName:NSDeviceRGBColorSpace
colorSpaceName:NSCalibratedRGBColorSpace
bitmapFormat:NSAlphaFirstBitmapFormat | kCGBitmapByteOrder32Big
bytesPerRow:bpr.integerValue
bitsPerPixel:bpp.integerValue];

currentCursor[MCCursorDictionaryRepresentationsKey] = @[ [rep representationUsingType:NSPNGFileType properties:nil] ];
currentCursor[MCCursorDictionaryRepresentationsKey] = @[ [rep representationUsingType:NSPNGFileType properties:@{}] ];
currentCursor[MCCursorDictionaryPointsWideKey] = wide;
currentCursor[MCCursorDictionaryPointsHighKey] = high;
currentCursor[MCCursorDictionaryHotSpotXKey] = hotX;
Expand Down Expand Up @@ -246,7 +246,10 @@
NSMutableArray *reps = [NSMutableArray array];

for (id image in cursors) {
reps[reps.count] = pngDataForImage(image);
CGImageRef im = (__bridge CGImageRef)image;
NSBitmapImageRep *rep = [[NSBitmapImageRep alloc] initWithCGImage:im];

reps[reps.count] = pngDataForImage(rep.ensuredSRGBSpace);
}

dict[MCCursorDictionaryRepresentationsKey] = reps;
Expand Down Expand Up @@ -393,4 +396,4 @@ extern void exportCape(NSDictionary *cape, NSString *destination) {
[data writeToFile:[destination stringByAppendingPathComponent:[NSString stringWithFormat:@"%@_%lu.png", key, (unsigned long)idx]] atomically:NO];
}
}
}
}

0 comments on commit b570903

Please sign in to comment.