Search code examples
iosobjective-copengl-eslibpngpremultiplied-alpha

Extract OpenGL raw RGB(A) texture data from png data stored in NSData using libpng on iOS


Unfortunately, there appears to be no way to using a built-in method on iOS to extract 32 bit RGBA data from a PNG file without losing the alpha channel reference. Therefore, some people have been using libpng to extract their OpenGL textures. However, all the examples have required the png file to be loaded from a file. Assuming these textures are imported over a network connection, they would have to be saved to files from NSData and then read. What is the best way to extract raw PNG data into raw OpenGL RGBA texture data?


Solution

  • Ended up writing a category which solves this problem using the customization capabilities of libpng. Posted a gist here: https://gist.github.com/joshcodes/5681512

    Hopefully this helps someone else who needs to know how this is done. The essential part is creating a method

    void user_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
    {
        void *nsDataPtr = png_get_io_ptr(png_ptr);
        ReadStream *readStream = (ReadStream*)nsDataPtr;
        memcpy(data, readStream->source + readStream->index, length);
        readStream->index += length;
    }
    

    and using

    // init png reading
    png_set_read_fn(png_ptr, &readStream, user_read_data);
    

    as a custom read method.