18b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <stdio.h>
28b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <stdlib.h>
38b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
48b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <png.h>
58b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
68b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if 0
78b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define LOG(x...) fprintf(stderr,"error: " x)
88b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
98b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define LOG(x...) do {} while (0)
108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid *loadpng(const char *fn, unsigned *_width, unsigned *_height)
138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    FILE *fp = 0;
158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    unsigned char header[8];
168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    unsigned char *data = 0;
178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    unsigned char **rowptrs = 0;
188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    png_structp p = 0;
198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    png_infop pi = 0;
208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    png_uint_32 width, height;
228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int bitdepth, colortype, imethod, cmethod, fmethod, i;
238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    p = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if(p == 0) {
268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        LOG("%s: failed to allocate png read struct\n", fn);
278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 0;
288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    pi = png_create_info_struct(p);
318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if(pi == 0) {
328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        LOG("%s: failed to allocate png info struct\n", fn);
338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        goto oops;
348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    fp = fopen(fn, "rb");
378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if(fp == 0) {
388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        LOG("%s: failed to open file\n", fn);
398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 0;
408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if(fread(header, 8, 1, fp) != 1) {
438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        LOG("%s: failed to read header\n", fn);
448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        goto oops;
458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if(png_sig_cmp(header, 0, 8)) {
488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        LOG("%s: header is not a PNG header\n", fn);
498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        goto oops;
508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if(setjmp(png_jmpbuf(p))) {
538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        LOG("%s: png library error\n", fn);
548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    oops:
558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        png_destroy_read_struct(&p, &pi, 0);
568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if(fp != 0) fclose(fp);
578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if(data != 0) free(data);
588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if(rowptrs != 0) free(rowptrs);
598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 0;
608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    png_init_io(p, fp);
638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    png_set_sig_bytes(p, 8);
648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    png_read_info(p, pi);
668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    png_get_IHDR(p, pi, &width, &height, &bitdepth, &colortype,
688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                 &imethod, &cmethod, &fmethod);
698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project//    printf("PNG: %d x %d (d=%d, c=%d)\n",
708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project//           width, height, bitdepth, colortype);
718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    switch(colortype){
738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case PNG_COLOR_TYPE_PALETTE:
748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        png_set_palette_to_rgb(p);
758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case PNG_COLOR_TYPE_RGB:
788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if(png_get_valid(p, pi, PNG_INFO_tRNS)) {
798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_set_tRNS_to_alpha(p);
808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        } else {
818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_set_filler(p, 0xff, PNG_FILLER_AFTER);
828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case PNG_COLOR_TYPE_RGB_ALPHA:
868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case PNG_COLOR_TYPE_GRAY:
898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if(bitdepth < 8) {
908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_set_gray_1_2_4_to_8(p);
918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    default:
948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        LOG("%s: unsupported (grayscale?) color type\n");
958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        goto oops;
968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if(bitdepth == 16) {
998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        png_set_strip_16(p);
1008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
1018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    data = (unsigned char*) malloc((width * 4) * height);
1038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    rowptrs = (unsigned char **) malloc(sizeof(unsigned char*) * height);
1048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if((data == 0) || (rowptrs == 0)){
1068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        LOG("could not allocate data buffer\n");
1078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        goto oops;
1088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
1098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for(i = 0; i < height; i++) {
1118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        rowptrs[i] = data + ((width * 4) * i);
1128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
1138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    png_read_image(p, rowptrs);
1158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    png_destroy_read_struct(&p, &pi, 0);
1178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    fclose(fp);
1188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if(rowptrs != 0) free(rowptrs);
1198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    *_width = width;
1218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    *_height = height;
1228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return (void*) data;
1248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttypedef struct
1288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    const unsigned char*  base;
1308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    const unsigned char*  end;
1318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    const unsigned char*  cursor;
1328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} PngReader;
1348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void
1368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_reader_read_data( png_structp  png_ptr,
1378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                      png_bytep   data,
1388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                      png_size_t  length )
1398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  PngReader* reader = png_get_io_ptr(png_ptr);
1418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  png_size_t avail  = (png_size_t)(reader->end - reader->cursor);
1428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  if (avail > length)
1448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      avail = length;
1458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  memcpy( data, reader->cursor, avail );
1478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  reader->cursor += avail;
1488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid *readpng(const unsigned char *base, size_t   size, unsigned *_width, unsigned *_height)
1528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    PngReader  reader;
1548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    unsigned char *data = 0;
1558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    unsigned char **rowptrs = 0;
1568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    png_structp p = 0;
1578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    png_infop pi = 0;
1588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    png_uint_32 width, height;
1608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int bitdepth, colortype, imethod, cmethod, fmethod, i;
1618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    p = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
1638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if(p == 0) {
1648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        LOG("%s: failed to allocate png read struct\n", fn);
1658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 0;
1668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
1678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    pi = png_create_info_struct(p);
1698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if(pi == 0) {
1708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        LOG("%s: failed to allocate png info struct\n", fn);
1718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        goto oops;
1728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
1738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    reader.base   = base;
1758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    reader.end    = base + size;
1768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    reader.cursor = base;
1778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if(size < 8 || png_sig_cmp((unsigned char*)base, 0, 8)) {
1798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        LOG("%s: header is not a PNG header\n", fn);
1808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        goto oops;
1818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
1828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    reader.cursor += 8;
1848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if(setjmp(png_jmpbuf(p))) {
1868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        LOG("%s: png library error\n", fn);
1878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    oops:
1888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        png_destroy_read_struct(&p, &pi, 0);
1898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if(data != 0) free(data);
1908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if(rowptrs != 0) free(rowptrs);
1918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 0;
1928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
1938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    png_set_read_fn (p, &reader, png_reader_read_data);
1958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    png_set_sig_bytes(p, 8);
1968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    png_read_info(p, pi);
1988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    png_get_IHDR(p, pi, &width, &height, &bitdepth, &colortype,
2008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                 &imethod, &cmethod, &fmethod);
2018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project//    printf("PNG: %d x %d (d=%d, c=%d)\n",
2028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project//           width, height, bitdepth, colortype);
2038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    switch(colortype){
2058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case PNG_COLOR_TYPE_PALETTE:
2068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        png_set_palette_to_rgb(p);
2078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
2088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case PNG_COLOR_TYPE_RGB:
2108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if(png_get_valid(p, pi, PNG_INFO_tRNS)) {
2118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_set_tRNS_to_alpha(p);
2128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        } else {
2138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_set_filler(p, 0xff, PNG_FILLER_AFTER);
2148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
2158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
2168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case PNG_COLOR_TYPE_RGB_ALPHA:
2188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
2198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case PNG_COLOR_TYPE_GRAY:
2218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if(bitdepth < 8) {
2228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_set_gray_1_2_4_to_8(p);
2238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
2248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    default:
2268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        LOG("%s: unsupported (grayscale?) color type\n");
2278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        goto oops;
2288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
2298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if(bitdepth == 16) {
2318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        png_set_strip_16(p);
2328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
2338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    data    = (unsigned char*) malloc((width * 4) * height);
2358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    rowptrs = (unsigned char **) malloc(sizeof(unsigned char*) * height);
2368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if((data == 0) || (rowptrs == 0)){
2388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        LOG("could not allocate data buffer\n");
2398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        goto oops;
2408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
2418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for(i = 0; i < height; i++) {
2438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        rowptrs[i] = data + ((width * 4) * i);
2448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
2458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    png_read_image(p, rowptrs);
2478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    png_destroy_read_struct(&p, &pi, 0);
2498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if(rowptrs != 0) free(rowptrs);
2508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    *_width = width;
2528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    *_height = height;
2538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return (void*) data;
2558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
2568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if 0
2598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint main(int argc, char **argv)
2608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
2618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    unsigned w,h;
2628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    unsigned char *data;
2638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if(argc < 2) return 0;
2658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    data = loadpng(argv[1], &w, &h);
2688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if(data != 0) {
2708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        printf("w: %d  h: %d\n", w, h);
2718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
2728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return 0;
2748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
2758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
276