X-Git-Url: https://git.lukelau.me/?p=opengl.git;a=blobdiff_plain;f=image.cpp;h=02fd60b878ee1122bd9a027e38df10304d681ef8;hp=71114b0d85c8f239800602b3e0e1fcfe0431493b;hb=d0c631f46c6db417e013b1bc0edec24cb9c2824a;hpb=c44e69ec78367fb2957324026894aef970f2481a diff --git a/image.cpp b/image.cpp index 71114b0..02fd60b 100644 --- a/image.cpp +++ b/image.cpp @@ -1,31 +1,74 @@ #include "image.hpp" +#include Image::Image(const std::string &path) { - auto provider = CGDataProviderCreateWithFilename(path.c_str()); - std::ifstream file(path); - long magic; - file.read((char*)&magic, 8); - file.close(); + CFStringRef str = CFStringCreateWithCString(NULL, path.c_str(), kCFStringEncodingUTF8); + CFURLRef url = CFURLCreateWithFileSystemPath(NULL, str, kCFURLPOSIXPathStyle, false); + CGImageSourceRef source = CGImageSourceCreateWithURL(url, NULL); + CGImageRef ref = CGImageSourceCreateImageAtIndex(source, 0, NULL); + initWithImageRef(ref); + CGImageRelease(ref); +} +Image::Image(const unsigned char *data, size_t length, const char *formatHint) { + CGDataProviderRef dpRef = CGDataProviderCreateWithData(NULL, data, length, NULL); CGImageRef ref; - - if (magic == 0x0a1a0a0d474e5089) // png magic number - ref = CGImageCreateWithPNGDataProvider(provider, nullptr, false, kCGRenderingIntentDefault); + if (strcmp("png", formatHint) == 0) + ref = CGImageCreateWithPNGDataProvider(dpRef, NULL, false, kCGRenderingIntentDefault); + else if (strcmp("jpg", formatHint) == 0) + ref = CGImageCreateWithJPEGDataProvider(dpRef, NULL, false, kCGRenderingIntentDefault); else - ref = CGImageCreateWithJPEGDataProvider(provider, nullptr, false, kCGRenderingIntentDefault); + abort(); + initWithImageRef(ref); + CGImageRelease(ref); +} +void Image::initWithImageRef(CGImageRef ref) { _width = CGImageGetWidth(ref), _height = CGImageGetHeight(ref); + info = CGImageGetBitmapInfo(ref); + alphaInfo = CGImageGetAlphaInfo(ref); + colorSpace = CGImageGetColorSpace(ref); + bitsPerComponent = CGImageGetBitsPerComponent(ref); dataRef = CGDataProviderCopyData(CGImageGetDataProvider(ref)); - CGImageRelease(ref); - } -unsigned char *Image::data() { +unsigned char *Image::data() const { return (unsigned char*) CFDataGetBytePtr(dataRef); } GLfloat Image::width() const { return _width; } GLfloat Image::height() const { return _height; } +// TODO: Properly implement this for both internal format + format +GLenum Image::format() const { + if (CGColorSpaceGetModel(colorSpace) == kCGColorSpaceModelMonochrome) { + return GL_DEPTH_COMPONENT; + } + if (alphaInfo == kCGImageAlphaNone) { + return GL_RGB; + } + return GL_RGBA; +} + +GLint Image::internalFormat() const { + switch (format()) { + case GL_DEPTH_COMPONENT: return GL_DEPTH_COMPONENT; + case GL_RGB: return GL_RGB; + default: return GL_RGBA; + } +} + +GLenum Image::type() const { + bool isFloat = info & kCGBitmapFloatComponents; + if (isFloat) return GL_FLOAT; + return GL_UNSIGNED_BYTE; + + //TODO: + /* switch (bitsPerComponent) { */ + /* case 1: return GL_UNSIGNED_BYTE; */ + /* case 16: return GL_UNSIGNED_SHORT; */ + /* case 24: */ +} + Image::~Image() { CFRelease(dataRef); }