165 lines
3.6 KiB
C
165 lines
3.6 KiB
C
#include <lib/InsPng.h>
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <setjmp.h>
|
|
#include <string.h>
|
|
|
|
#include <zlib.h>
|
|
#include <png.h>
|
|
#include <pngstruct.h>
|
|
#include <pnginfo.h>
|
|
|
|
typedef struct Struct_MemPng
|
|
{
|
|
UInt08 *data;
|
|
Int32 size;
|
|
Int32 offset;
|
|
} MemPng;
|
|
|
|
static void callback_ReadMemPng(png_structp ptrPng, png_bytep data, png_size_t length)
|
|
{
|
|
MemPng *mPngSrc = (MemPng*)ptrPng->io_ptr;
|
|
if(mPngSrc == NULL)
|
|
{
|
|
png_error(ptrPng, "not mem png source define");
|
|
}
|
|
else if(mPngSrc->offset + length <= mPngSrc->size)
|
|
{
|
|
memcpy(data, mPngSrc->data+mPngSrc->offset, length);
|
|
mPngSrc->offset += length;
|
|
}
|
|
else
|
|
{
|
|
png_error(ptrPng, "more mem png data is needed");
|
|
}
|
|
}
|
|
|
|
/*RGB888 only*/
|
|
Bool LoadPngFromMem(void *mem, UInt32 memSz, Int32 *width, Int32 *height, UInt32 *format, void **bmp, UInt32 bmpSize)
|
|
{
|
|
Int32 i, j, w, h, type;
|
|
UInt32 fmt;
|
|
MemPng mSrc =
|
|
{
|
|
.data = mem,
|
|
.size = memSz,
|
|
.offset = 0
|
|
};
|
|
UInt08 *buff;
|
|
#define GL_RGB 0x1907
|
|
#define GL_RGBA 0x1908
|
|
|
|
png_structp ptrPng = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
|
|
if(ptrPng == 0)return INS_FALSE;
|
|
|
|
png_infop ptrInfo = png_create_info_struct(ptrPng);
|
|
if(ptrInfo == 0)
|
|
{
|
|
png_destroy_read_struct(&ptrPng, 0, 0);
|
|
return INS_FALSE;
|
|
}
|
|
|
|
if(setjmp(png_jmpbuf(ptrPng)))
|
|
{
|
|
png_destroy_read_struct(&ptrPng, 0, 0);
|
|
return INS_FALSE;
|
|
}
|
|
|
|
png_set_read_fn(ptrPng, &mSrc, callback_ReadMemPng);
|
|
png_read_png(ptrPng, ptrInfo, PNG_TRANSFORM_EXPAND, 0);
|
|
|
|
w = ptrInfo->width;
|
|
h = ptrInfo->height;
|
|
// depth = ptrInfo->pixel_depth;
|
|
png_bytep *PtrRow = png_get_rows(ptrPng, ptrInfo);
|
|
type = ptrInfo->color_type;
|
|
|
|
switch(type)
|
|
{
|
|
case PNG_COLOR_TYPE_RGB:
|
|
if(bmp[0] != NULL && bmpSize > 0)
|
|
{
|
|
if(w*h*3 > bmpSize)
|
|
{
|
|
png_destroy_read_struct(&ptrPng, 0, 0);
|
|
return INS_FALSE;
|
|
}
|
|
}
|
|
else if(bmp[0] == NULL)
|
|
{
|
|
bmp[0] = malloc(w*h*3);
|
|
}
|
|
else
|
|
{
|
|
png_destroy_read_struct(&ptrPng, 0, 0);
|
|
return INS_FALSE;
|
|
}
|
|
buff = bmp[0];
|
|
fmt = GL_RGB;
|
|
for(i = 0; i < h; i++)
|
|
{
|
|
for(j = 0; j < w; j++)
|
|
{
|
|
buff[3*((h-1-i)*w+j)+0] = PtrRow[i][3*j+0];
|
|
buff[3*((h-1-i)*w+j)+1] = PtrRow[i][3*j+1];
|
|
buff[3*((h-1-i)*w+j)+2] = PtrRow[i][3*j+2];
|
|
}
|
|
}
|
|
break;
|
|
case PNG_COLOR_TYPE_RGBA:
|
|
if(bmp[0] != NULL && bmpSize > 0)
|
|
{
|
|
if(w*h*4 > bmpSize)
|
|
{
|
|
png_destroy_read_struct(&ptrPng, 0, 0);
|
|
return INS_FALSE;
|
|
}
|
|
}
|
|
else if(bmp[0] == NULL)
|
|
{
|
|
bmp[0] = malloc(w*h*4);
|
|
}
|
|
else
|
|
{
|
|
png_destroy_read_struct(&ptrPng, 0, 0);
|
|
return INS_FALSE;
|
|
}
|
|
buff = bmp[0];
|
|
fmt = GL_RGBA;
|
|
for(i = 0; i < h; i++)
|
|
{
|
|
for(j = 0; j < w; j++)
|
|
{
|
|
buff[4*((h-1-i)*w+j)+0] = PtrRow[i][4*j+0];
|
|
buff[4*((h-1-i)*w+j)+1] = PtrRow[i][4*j+1];
|
|
buff[4*((h-1-i)*w+j)+2] = PtrRow[i][4*j+2];
|
|
buff[4*((h-1-i)*w+j)+3] = PtrRow[i][4*j+3];
|
|
}
|
|
}
|
|
break;
|
|
default:
|
|
png_destroy_read_struct(&ptrPng, 0, 0);
|
|
return INS_FALSE;
|
|
}
|
|
|
|
*width = w;
|
|
*height = h;
|
|
*format = fmt;
|
|
|
|
return INS_TRUE;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|