Handle loading of embedded textures
[opengl.git] / image.cpp
1 #include "image.hpp"
2 #include <ImageIO/ImageIO.h>
3
4 Image::Image(const std::string &path) {
5         CFStringRef str = CFStringCreateWithCString(NULL, path.c_str(), kCFStringEncodingUTF8);
6         CFURLRef url = CFURLCreateWithFileSystemPath(NULL, str, kCFURLPOSIXPathStyle, false);
7         CGImageSourceRef source = CGImageSourceCreateWithURL(url, NULL);
8         CGImageRef ref = CGImageSourceCreateImageAtIndex(source, 0, NULL);
9         initWithImageRef(ref);
10         CGImageRelease(ref);
11 }
12
13 Image::Image(const unsigned char *data, size_t length) {
14         CGDataProviderRef dpRef = CGDataProviderCreateWithData(NULL, data, length, NULL);
15         CGImageRef ref = CGImageCreateWithJPEGDataProvider(dpRef, NULL, false, kCGRenderingIntentDefault);
16         initWithImageRef(ref);
17         CGImageRelease(ref);
18 }
19
20 void Image::initWithImageRef(CGImageRef ref) {
21         _width = CGImageGetWidth(ref), _height = CGImageGetHeight(ref);
22         info = CGImageGetBitmapInfo(ref);
23         alphaInfo = CGImageGetAlphaInfo(ref);
24         colorSpace = CGImageGetColorSpace(ref);
25         bitsPerComponent = CGImageGetBitsPerComponent(ref);
26
27         dataRef = CGDataProviderCopyData(CGImageGetDataProvider(ref));
28 }
29
30 unsigned char *Image::data() const {
31         return (unsigned char*) CFDataGetBytePtr(dataRef);
32 }
33
34 GLfloat Image::width() const { return _width; }
35 GLfloat Image::height() const { return _height; }
36
37 // TODO: Properly implement this for both internal format + format
38 GLenum Image::format() const {
39         if (CGColorSpaceGetModel(colorSpace) == kCGColorSpaceModelMonochrome) {
40                 return GL_DEPTH_COMPONENT;
41         }
42         if (alphaInfo == kCGImageAlphaNone) {
43                 return GL_RGB;
44         }
45         return GL_RGBA;
46 }
47
48 GLint Image::internalFormat() const {
49         switch (format()) {
50                 case GL_DEPTH_COMPONENT: return GL_DEPTH_COMPONENT;
51                 case GL_RGB: return GL_RGB;
52                 default: return GL_RGBA;
53         }
54 }
55
56 GLenum Image::type() const {
57         bool isFloat = info & kCGBitmapFloatComponents;
58         if (isFloat) return GL_FLOAT;
59         return GL_UNSIGNED_BYTE;
60         
61         //TODO:
62         /* switch (bitsPerComponent) { */
63         /*      case 1: return GL_UNSIGNED_BYTE; */
64         /*      case 16: return GL_UNSIGNED_SHORT; */
65         /*  case 24: */ 
66 }
67
68 Image::~Image() { CFRelease(dataRef); }