feat():initial version
This commit is contained in:
164
insDavi2.0/src/lib/InsPng.c
Normal file
164
insDavi2.0/src/lib/InsPng.c
Normal file
@@ -0,0 +1,164 @@
|
||||
#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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user