Fix metal roughness texture on streaked metal material
[opengl.git] / image.cpp
index 71114b0d85c8f239800602b3e0e1fcfe0431493b..02fd60b878ee1122bd9a027e38df10304d681ef8 100644 (file)
--- a/image.cpp
+++ b/image.cpp
@@ -1,31 +1,74 @@
 #include "image.hpp"
 #include "image.hpp"
+#include <ImageIO/ImageIO.h>
 
 Image::Image(const std::string &path) {
 
 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;
        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
        else
-               ref = CGImageCreateWithJPEGDataProvider(provider, nullptr, false, kCGRenderingIntentDefault);
+               abort();
+       initWithImageRef(ref);
+       CGImageRelease(ref);
+}
 
 
+void Image::initWithImageRef(CGImageRef ref) {
        _width = CGImageGetWidth(ref), _height = CGImageGetHeight(ref);
        _width = CGImageGetWidth(ref), _height = CGImageGetHeight(ref);
+       info = CGImageGetBitmapInfo(ref);
+       alphaInfo = CGImageGetAlphaInfo(ref);
+       colorSpace = CGImageGetColorSpace(ref);
+       bitsPerComponent = CGImageGetBitsPerComponent(ref);
 
        dataRef = CGDataProviderCopyData(CGImageGetDataProvider(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; }
 
        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); }
 Image::~Image() { CFRelease(dataRef); }