Created
August 9, 2024 20:38
-
-
Save ccgus/335a9e96e3514d89ba3fc2e37b5316c1 to your computer and use it in GitHub Desktop.
The Case of the Missing Pixel.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// 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