Skip to content

Instantly share code, notes, and snippets.

@ccgus
Created August 9, 2024 20:38
Show Gist options
  • Save ccgus/335a9e96e3514d89ba3fc2e37b5316c1 to your computer and use it in GitHub Desktop.
Save ccgus/335a9e96e3514d89ba3fc2e37b5316c1 to your computer and use it in GitHub Desktop.
The Case of the Missing Pixel.
//
// main.m
// TheCaseOfTheMissingPixel
//
// Created by August Mueller on 3/13/24.
//
#import <AppKit/AppKit.h>
/*
FB13687028
clang -x objective-c -framework AppKit main.m; ./a.out
Drawing an RGB image to a GenericGrayGamma2_2 CGBitmapContext inserts artifacts
We're going to draw a single vertical line on an 8x8 RGB white bitmap context
Then we're going to make a CGImageRef from that context, and then draw that to a
8x8 GenericGrayGamma2_2 bitmap context.
What happens is an extra pixel is then thrown in the bottom right corner.
Which is bad.
*/
void writeAndOpenImageAtPath(CGImageRef img, NSString *path);
int main(int argc, const char * argv[]) {
@autoreleasepool {
CGColorSpaceRef cs = CGColorSpaceCreateWithName(kCGColorSpaceSRGB);
CGBitmapInfo options = (CGBitmapInfo)kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big;
size_t bitsPerComponent = 8;
size_t width = 8;
size_t height = 8;
CGContextRef bitmapContext = CGBitmapContextCreate(nil, width, height, bitsPerComponent, 0, cs, options);
assert(bitmapContext);
CGContextSetBlendMode(bitmapContext, kCGBlendModeCopy);
CGContextSetRGBFillColor(bitmapContext, 1, 1, 1, 1);
CGContextFillRect(bitmapContext, CGRectMake(0, 0, width, height));
CGContextSetRGBFillColor(bitmapContext, 0, 0, 0, 1);
CGContextFillRect(bitmapContext, CGRectMake(width-2, 0, 1, height));
CGImageRef rgbImage = CGBitmapContextCreateImage(bitmapContext);
writeAndOpenImageAtPath(rgbImage, @"/tmp/rgbImage.png");
CGColorSpaceRef greycs = CGColorSpaceCreateWithName(kCGColorSpaceGenericGrayGamma2_2);
CGContextRef greyBitmapContext = CGBitmapContextCreate(nil, width, height, bitsPerComponent, 0, greycs, (CGBitmapInfo)kCGImageAlphaPremultipliedLast);
assert(greyBitmapContext);
CGContextDrawImage(greyBitmapContext, CGRectMake(0, 0, width, height), rgbImage);
CGImageRef grayImage = CGBitmapContextCreateImage(greyBitmapContext);
writeAndOpenImageAtPath(grayImage, @"/tmp/grayImage.png");
printf("All done!\n");
}
return 0;
}
void writeAndOpenImageAtPath(CGImageRef img, NSString *path) {
system([[NSString stringWithFormat:@"rm %@", path] UTF8String]);
NSURL *writeURL = [NSURL fileURLWithPath:path];
CGImageDestinationRef imageDestination = CGImageDestinationCreateWithURL((__bridge CFURLRef)writeURL, (__bridge CFStringRef)@"public.png", 1, NULL);
CGImageDestinationAddImage(imageDestination, img, (__bridge CFDictionaryRef)@{});
assert(CGImageDestinationFinalize(imageDestination));
system([[NSString stringWithFormat:@"open %@", path] UTF8String]);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment