mirror of
https://github.com/dborth/fceugx.git
synced 2024-10-31 22:45:05 +01:00
optimizations
This commit is contained in:
parent
3a64a766be
commit
669528b681
@ -51,14 +51,13 @@ static struct
|
||||
static int f_read(void * punt, int bytes, int blocks, int *f)
|
||||
{
|
||||
int b;
|
||||
int c;
|
||||
int c = 0;
|
||||
int d;
|
||||
|
||||
if (bytes * blocks <= 0)
|
||||
return 0;
|
||||
|
||||
blocks = bytes * blocks;
|
||||
c = 0;
|
||||
blocks *= bytes;
|
||||
|
||||
while (blocks > 0)
|
||||
{
|
||||
@ -66,9 +65,9 @@ static int f_read(void * punt, int bytes, int blocks, int *f)
|
||||
if (b > 4096)
|
||||
b = 4096;
|
||||
|
||||
if (*f >= 0x666 && *f <= 0x669)
|
||||
d = (*f) - 0x666;
|
||||
if((unsigned)(d) <= (0x669 - 0x666))
|
||||
{
|
||||
d = (*f) - 0x666;
|
||||
if (file[d].size == 0)
|
||||
return -1;
|
||||
if ((file[d].pos + b) > file[d].size)
|
||||
@ -96,11 +95,12 @@ static int f_seek(int *f, ogg_int64_t offset, int mode)
|
||||
{
|
||||
if(f==NULL) return(-1);
|
||||
|
||||
int k, d;
|
||||
int k;
|
||||
mode &= 3;
|
||||
if (*f >= 0x666 && *f <= 0x669)
|
||||
|
||||
int d = (*f) - 0x666;
|
||||
if((unsigned)(d) <= (0x669 - 0x666))
|
||||
{
|
||||
d = (*f) - 0x666;
|
||||
k = 0;
|
||||
|
||||
if (file[d].size == 0)
|
||||
@ -121,7 +121,7 @@ static int f_seek(int *f, ogg_int64_t offset, int mode)
|
||||
else
|
||||
file[d].pos = offset;
|
||||
}
|
||||
if (mode == 1)
|
||||
else if (mode == 1)
|
||||
{
|
||||
if ((file[d].pos + offset) >= file[d].size)
|
||||
{
|
||||
@ -136,7 +136,7 @@ static int f_seek(int *f, ogg_int64_t offset, int mode)
|
||||
else
|
||||
file[d].pos += offset;
|
||||
}
|
||||
if (mode == 2)
|
||||
else if (mode == 2)
|
||||
{
|
||||
|
||||
if ((file[d].size + offset) >= file[d].size)
|
||||
@ -166,10 +166,9 @@ static int f_seek(int *f, ogg_int64_t offset, int mode)
|
||||
|
||||
static int f_close(int *f)
|
||||
{
|
||||
int d;
|
||||
if (*f >= 0x666 && *f <= 0x669)
|
||||
int d = (*f) - 0x666;
|
||||
if((unsigned)(d) <= (0x669 - 0x666))
|
||||
{
|
||||
d = (*f) - 0x666;
|
||||
file[d].size = 0;
|
||||
file[d].pos = 0;
|
||||
if (file[d].mem)
|
||||
@ -185,11 +184,11 @@ static int f_close(int *f)
|
||||
|
||||
static long f_tell(int *f)
|
||||
{
|
||||
int k, d;
|
||||
int k;
|
||||
|
||||
if (*f >= 0x666 && *f <= 0x669)
|
||||
int d = (*f) - 0x666;
|
||||
if((unsigned)(d) <= (0x669 - 0x666))
|
||||
{
|
||||
d = (*f) - 0x666;
|
||||
k = file[d].pos;
|
||||
}
|
||||
else
|
||||
@ -205,8 +204,15 @@ static int mem_open(char * ogg, int size)
|
||||
if (one)
|
||||
{
|
||||
one = 0;
|
||||
for (n = 0; n < 4; n++)
|
||||
file[n].size = 0;
|
||||
|
||||
file[0].size = 0;
|
||||
file[1].size = 0;
|
||||
file[2].size = 0;
|
||||
file[3].size = 0;
|
||||
file[0].mem = ogg;
|
||||
file[0].size = size;
|
||||
file[0].pos = 0;
|
||||
return (0x666);
|
||||
}
|
||||
|
||||
for (n = 0; n < 4; n++)
|
||||
@ -224,7 +230,7 @@ static int mem_open(char * ogg, int size)
|
||||
|
||||
static int mem_close(int fd)
|
||||
{
|
||||
if (fd >= 0x666 && fd <= 0x669) // it is a memory file descriptor?
|
||||
if((unsigned)((fd) - 0x666) <= (0x669 - 0x666)) // it is a memory file descriptor?
|
||||
{
|
||||
fd -= 0x666;
|
||||
file[fd].size = 0;
|
||||
@ -353,8 +359,7 @@ static void * ogg_player_thread(private_data_ogg * priv)
|
||||
priv[0].seek_time = -1;
|
||||
}
|
||||
|
||||
ret
|
||||
= ov_read(
|
||||
ret = ov_read(
|
||||
&priv[0].vf,
|
||||
(void *) &priv[0].pcmout[priv[0].pcmout_pos][priv[0].pcm_indx],
|
||||
MAX_PCMOUT,/*0,2,1,*/&priv[0].current_section);
|
||||
@ -513,8 +518,7 @@ int StatusOgg()
|
||||
return 255; // EOF
|
||||
else if (private_ogg.flag & 128)
|
||||
return 2; // paused
|
||||
else
|
||||
return 1; // running
|
||||
return 1; // running
|
||||
}
|
||||
|
||||
void SetVolumeOgg(int volume)
|
||||
|
@ -47,7 +47,7 @@ struct _IMGCTX
|
||||
png_bytep img_data;
|
||||
};
|
||||
|
||||
// PNGU Implementation //
|
||||
// PNGU Implementation
|
||||
|
||||
IMGCTX PNGU_SelectImageFromBuffer (const void *buffer)
|
||||
{
|
||||
@ -129,436 +129,6 @@ int PNGU_GetImageProperties (IMGCTX ctx, PNGUPROP *imgprop)
|
||||
return PNGU_OK;
|
||||
}
|
||||
|
||||
int PNGU_DecodeToYCbYCr (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *buffer, PNGU_u32 stride)
|
||||
{
|
||||
int result;
|
||||
PNGU_u32 x, y, buffWidth;
|
||||
|
||||
// width needs to be divisible by two
|
||||
if (width % 2)
|
||||
return PNGU_ODD_WIDTH;
|
||||
|
||||
// stride needs to be divisible by two
|
||||
if (stride % 2)
|
||||
return PNGU_ODD_STRIDE;
|
||||
|
||||
result = pngu_decode (ctx, width, height, 1);
|
||||
if (result != PNGU_OK)
|
||||
return result;
|
||||
|
||||
// Copy image to the output buffer
|
||||
buffWidth = (width + stride) >> 1;
|
||||
PNGU_u32 wid2 = width >>1;
|
||||
for (y = 0; y < height; y++)
|
||||
{
|
||||
for (x = 0; x < wid2; x++)
|
||||
{
|
||||
PNGU_u32 x6 = x*6;
|
||||
((PNGU_u32 *)buffer)[y*buffWidth+x] = PNGU_RGB8_TO_YCbYCr (*(ctx->row_pointers[y]+x6), *(ctx->row_pointers[y]+x6+1), *(ctx->row_pointers[y]+x6+2),
|
||||
*(ctx->row_pointers[y]+x6+3), *(ctx->row_pointers[y]+x6+4), *(ctx->row_pointers[y]+x6+5));
|
||||
}
|
||||
}
|
||||
|
||||
// Free resources
|
||||
free (ctx->img_data);
|
||||
free (ctx->row_pointers);
|
||||
|
||||
// Success
|
||||
return PNGU_OK;
|
||||
}
|
||||
|
||||
int PNGU_DecodeToRGB565 (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *buffer, PNGU_u32 stride)
|
||||
{
|
||||
int result;
|
||||
PNGU_u32 x, y, buffWidth;
|
||||
|
||||
result = pngu_decode (ctx, width, height, 1);
|
||||
if (result != PNGU_OK)
|
||||
return result;
|
||||
|
||||
buffWidth = width + stride;
|
||||
|
||||
// Copy image to the output buffer
|
||||
for (y = 0; y < height; y++)
|
||||
for (x = 0; x < width; x++)
|
||||
((PNGU_u16 *)buffer)[y*buffWidth+x] =
|
||||
(((PNGU_u16) (ctx->row_pointers[y][x*3] & 0xF8)) << 8) |
|
||||
(((PNGU_u16) (ctx->row_pointers[y][x*3+1] & 0xFC)) << 3) |
|
||||
(((PNGU_u16) (ctx->row_pointers[y][x*3+2] & 0xF8)) >> 3);
|
||||
|
||||
// Free resources
|
||||
free (ctx->img_data);
|
||||
free (ctx->row_pointers);
|
||||
|
||||
// Success
|
||||
return PNGU_OK;
|
||||
}
|
||||
|
||||
int PNGU_DecodeToRGBA8 (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *buffer, PNGU_u32 stride, PNGU_u8 default_alpha)
|
||||
{
|
||||
int result;
|
||||
PNGU_u32 x, y, buffWidth;
|
||||
|
||||
result = pngu_decode (ctx, width, height, 0);
|
||||
if (result != PNGU_OK)
|
||||
return result;
|
||||
|
||||
buffWidth = width + stride;
|
||||
|
||||
// Check is source image has an alpha channel
|
||||
if ( (ctx->prop.imgColorType == PNGU_COLOR_TYPE_GRAY_ALPHA) || (ctx->prop.imgColorType == PNGU_COLOR_TYPE_RGB_ALPHA) )
|
||||
{
|
||||
// Alpha channel present, copy image to the output buffer
|
||||
for (y = 0; y < height; y++)
|
||||
memcpy (buffer + (y * buffWidth << 2), ctx->row_pointers[y], width<<2);
|
||||
}
|
||||
else
|
||||
{
|
||||
// No alpha channel present, copy image to the output buffer
|
||||
for (y = 0; y < height; y++)
|
||||
for (x = 0; x < width; x++)
|
||||
((PNGU_u32 *)buffer)[y*buffWidth+x] =
|
||||
(((PNGU_u32) ctx->row_pointers[y][x*3]) << 24) |
|
||||
(((PNGU_u32) ctx->row_pointers[y][x*3+1]) << 16) |
|
||||
(((PNGU_u32) ctx->row_pointers[y][x*3+2]) << 8) |
|
||||
((PNGU_u32) default_alpha);
|
||||
}
|
||||
|
||||
// Free resources
|
||||
free (ctx->img_data);
|
||||
free (ctx->row_pointers);
|
||||
|
||||
// Success
|
||||
return PNGU_OK;
|
||||
}
|
||||
|
||||
int PNGU_DecodeTo4x4RGB565 (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *buffer)
|
||||
{
|
||||
PNGU_u32 x, y;
|
||||
|
||||
// width and height need to be divisible by four
|
||||
if ((width % 4) || (height % 4))
|
||||
return PNGU_INVALID_WIDTH_OR_HEIGHT;
|
||||
|
||||
int result = pngu_decode (ctx, width, height, 1);
|
||||
if (result != PNGU_OK)
|
||||
return result;
|
||||
|
||||
// Copy image to the output buffer
|
||||
PNGU_u32 qwidth = width >> 2;
|
||||
PNGU_u32 qheight = height >> 2;
|
||||
|
||||
for (y = 0; y < qheight; y++)
|
||||
for (x = 0; x < qwidth; x++)
|
||||
{
|
||||
PNGU_u32 y4 = y << 2;
|
||||
PNGU_u32 x12 = x * 12;
|
||||
int blockbase = (y * qwidth + x) << 2;
|
||||
|
||||
PNGU_u64 field64 = *((PNGU_u64 *)(ctx->row_pointers[y4]+x12));
|
||||
PNGU_u64 field32 = (PNGU_u64) *((PNGU_u32 *)(ctx->row_pointers[y4]+x12+8));
|
||||
((PNGU_u64 *) buffer)[blockbase] =
|
||||
(((field64 & 0xF800000000000000ULL) | ((field64 & 0xFC000000000000ULL) << 3) | ((field64 & 0xF80000000000ULL) << 5)) |
|
||||
(((field64 & 0xF800000000ULL) << 8) | ((field64 & 0xFC000000ULL) << 11) | ((field64 & 0xF80000ULL) << 13)) |
|
||||
(((field64 & 0xF800ULL) << 16) | ((field64 & 0xFCULL) << 19) | ((field32 & 0xF8000000ULL) >> 11)) |
|
||||
(((field32 & 0xF80000ULL) >> 8) | ((field32 & 0xFC00ULL) >> 5) | ((field32 & 0xF8ULL) >> 3)));
|
||||
|
||||
field64 = *((PNGU_u64 *)(ctx->row_pointers[y4+1]+x12));
|
||||
field32 = (PNGU_u64) *((PNGU_u32 *)(ctx->row_pointers[y4+1]+x12+8));
|
||||
((PNGU_u64 *) buffer)[blockbase+1] =
|
||||
(((field64 & 0xF800000000000000ULL) | ((field64 & 0xFC000000000000ULL) << 3) | ((field64 & 0xF80000000000ULL) << 5)) |
|
||||
(((field64 & 0xF800000000ULL) << 8) | ((field64 & 0xFC000000ULL) << 11) | ((field64 & 0xF80000ULL) << 13)) |
|
||||
(((field64 & 0xF800ULL) << 16) | ((field64 & 0xFCULL) << 19) | ((field32 & 0xF8000000ULL) >> 11)) |
|
||||
(((field32 & 0xF80000ULL) >> 8) | ((field32 & 0xFC00ULL) >> 5) | ((field32 & 0xF8ULL) >> 3)));
|
||||
|
||||
field64 = *((PNGU_u64 *)(ctx->row_pointers[y4+2]+x12));
|
||||
field32 = (PNGU_u64) *((PNGU_u32 *)(ctx->row_pointers[y4+2]+x12+8));
|
||||
((PNGU_u64 *) buffer)[blockbase+2] =
|
||||
(((field64 & 0xF800000000000000ULL) | ((field64 & 0xFC000000000000ULL) << 3) | ((field64 & 0xF80000000000ULL) << 5)) |
|
||||
(((field64 & 0xF800000000ULL) << 8) | ((field64 & 0xFC000000ULL) << 11) | ((field64 & 0xF80000ULL) << 13)) |
|
||||
(((field64 & 0xF800ULL) << 16) | ((field64 & 0xFCULL) << 19) | ((field32 & 0xF8000000ULL) >> 11)) |
|
||||
(((field32 & 0xF80000ULL) >> 8) | ((field32 & 0xFC00ULL) >> 5) | ((field32 & 0xF8ULL) >> 3)));
|
||||
|
||||
field64 = *((PNGU_u64 *)(ctx->row_pointers[y4+3]+x12));
|
||||
field32 = (PNGU_u64) *((PNGU_u32 *)(ctx->row_pointers[y4+3]+x12+8));
|
||||
((PNGU_u64 *) buffer)[blockbase+3] =
|
||||
(((field64 & 0xF800000000000000ULL) | ((field64 & 0xFC000000000000ULL) << 3) | ((field64 & 0xF80000000000ULL) << 5)) |
|
||||
(((field64 & 0xF800000000ULL) << 8) | ((field64 & 0xFC000000ULL) << 11) | ((field64 & 0xF80000ULL) << 13)) |
|
||||
(((field64 & 0xF800ULL) << 16) | ((field64 & 0xFCULL) << 19) | ((field32 & 0xF8000000ULL) >> 11)) |
|
||||
(((field32 & 0xF80000ULL) >> 8) | ((field32 & 0xFC00ULL) >> 5) | ((field32 & 0xF8ULL) >> 3)));
|
||||
}
|
||||
|
||||
// Free resources
|
||||
free (ctx->img_data);
|
||||
free (ctx->row_pointers);
|
||||
|
||||
// Success
|
||||
return PNGU_OK;
|
||||
}
|
||||
|
||||
int PNGU_DecodeTo4x4RGB5A3 (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *buffer, PNGU_u8 default_alpha)
|
||||
{
|
||||
int result;
|
||||
PNGU_u32 x, y, qwidth, qheight;
|
||||
PNGU_u64 alphaMask;
|
||||
|
||||
// width and height need to be divisible by four
|
||||
if ((width % 4) || (height % 4))
|
||||
return PNGU_INVALID_WIDTH_OR_HEIGHT;
|
||||
|
||||
result = pngu_decode (ctx, width, height, 0);
|
||||
if (result != PNGU_OK)
|
||||
return result;
|
||||
|
||||
// Init some vars
|
||||
qwidth = width >> 2;
|
||||
qheight = height >> 2;
|
||||
|
||||
// Check is source image has an alpha channel
|
||||
if ( (ctx->prop.imgColorType == PNGU_COLOR_TYPE_GRAY_ALPHA) || (ctx->prop.imgColorType == PNGU_COLOR_TYPE_RGB_ALPHA) )
|
||||
{
|
||||
// Alpha channel present, copy image to the output buffer
|
||||
for (y = 0; y < qheight; y++)
|
||||
for (x = 0; x < qwidth; x++)
|
||||
{
|
||||
int blockbase = (y * qwidth + x) << 2;
|
||||
|
||||
PNGU_u32 y4 = y << 2;
|
||||
PNGU_u32 x16 = x << 4;
|
||||
|
||||
PNGU_u64 tmp;
|
||||
|
||||
PNGU_u64 fieldA = *((PNGU_u64 *)(ctx->row_pointers[y4]+x16));
|
||||
PNGU_u64 fieldB = *((PNGU_u64 *)(ctx->row_pointers[y4]+x16+8));
|
||||
|
||||
// If first pixel is opaque set MSB to 1 and encode colors in RGB555, else set MSB to 0 and encode colors in ARGB3444
|
||||
if ((fieldA & 0xE000000000ULL) == 0xE000000000ULL)
|
||||
tmp = 0x8000000000000000ULL | ((fieldA & 0xF800000000000000ULL) >> 1) | ((fieldA & 0xF8000000000000ULL) << 2) | ((fieldA & 0xF80000000000ULL) << 5);
|
||||
else
|
||||
tmp = ((fieldA & 0xE000000000ULL) << 23) | ((fieldA & 0xF000000000000000ULL) >> 4) | (fieldA & 0xF0000000000000ULL) | ((fieldA & 0xF00000000000ULL) << 4);
|
||||
|
||||
// If second pixel is opaque set MSB to 1 and encode colors in RGB555, else set MSB to 0 and encode colors in ARGB3444
|
||||
if ((fieldA & 0xE0ULL) == 0xE0ULL)
|
||||
tmp |= 0x800000000000ULL | ((fieldA & 0xF8000000ULL) << 15) | ((fieldA & 0xF80000ULL) << 18) | ((fieldA & 0xF800ULL) << 21);
|
||||
else
|
||||
tmp |= ((fieldA & 0xE0ULL) << 39) | ((fieldA & 0xF0000000ULL) << 12) | ((fieldA & 0xF00000ULL) << 16) | ((fieldA & 0xF000ULL) << 20);
|
||||
|
||||
// If third pixel is opaque set MSB to 1 and encode colors in RGB555, else set MSB to 0 and encode colors in ARGB3444
|
||||
if ((fieldB & 0xE000000000ULL) == 0xE000000000ULL)
|
||||
tmp |= 0x80000000ULL | ((fieldB & 0xF800000000000000ULL) >> 33) | ((fieldB & 0xF8000000000000ULL) >> 30) | ((fieldB & 0xF80000000000ULL) >> 27);
|
||||
else
|
||||
tmp |= ((fieldB & 0xE000000000ULL) >> 9) | ((fieldB & 0xF000000000000000ULL) >> 36) | ((fieldB & 0xF0000000000000ULL) >> 32) | ((fieldB & 0xF00000000000ULL) >> 28);
|
||||
|
||||
// If fourth pixel is opaque set MSB to 1 and encode colors in RGB555, else set MSB to 0 and encode colors in ARGB3444
|
||||
if ((fieldB & 0xE0ULL) == 0xE0ULL)
|
||||
tmp = tmp | 0x8000ULL | ((fieldB & 0xF8000000ULL) >> 17) | ((fieldB & 0xF80000ULL) >> 14) | ((fieldB & 0xF800ULL) >> 11);
|
||||
else
|
||||
tmp = tmp | ((fieldB & 0xE0ULL) << 7) | ((fieldB & 0xF0000000ULL) >> 20) | ((fieldB & 0xF00000ULL) >> 16) | ((fieldB & 0xF000ULL) >> 12);
|
||||
((PNGU_u64 *) buffer)[blockbase] = tmp;
|
||||
|
||||
fieldA = *((PNGU_u64 *)(ctx->row_pointers[y4+1]+x16));
|
||||
fieldB = *((PNGU_u64 *)(ctx->row_pointers[y4+1]+x16+8));
|
||||
if ((fieldA & 0xE000000000ULL) == 0xE000000000ULL)
|
||||
// Opaque pixel, so set MSB to 1 and encode colors in RGB555
|
||||
tmp = 0x8000000000000000ULL | ((fieldA & 0xF800000000000000ULL) >> 1) | ((fieldA & 0xF8000000000000ULL) << 2) | ((fieldA & 0xF80000000000ULL) << 5);
|
||||
else
|
||||
// Tranlucid pixel, so set MSB to 0 and encode colors in ARGB3444
|
||||
tmp = ((fieldA & 0xE000000000ULL) << 23) | ((fieldA & 0xF000000000000000ULL) >> 4) | (fieldA & 0xF0000000000000ULL) | ((fieldA & 0xF00000000000ULL) << 4);
|
||||
|
||||
if ((fieldA & 0xE0ULL) == 0xE0ULL)
|
||||
// Opaque pixel, so set MSB to 1 and encode colors in RGB555
|
||||
tmp |= 0x800000000000ULL | ((fieldA & 0xF8000000ULL) << 15) | ((fieldA & 0xF80000ULL) << 18) | ((fieldA & 0xF800ULL) << 21);
|
||||
else
|
||||
// Tranlucid pixel, so set MSB to 0 and encode colors in ARGB3444
|
||||
tmp |= ((fieldA & 0xE0ULL) << 39) | ((fieldA & 0xF0000000ULL) << 12) | ((fieldA & 0xF00000ULL) << 16) | ((fieldA & 0xF000ULL) << 20);
|
||||
|
||||
if ((fieldB & 0xE000000000ULL) == 0xE000000000ULL)
|
||||
// Opaque pixel, so set MSB to 1 and encode colors in RGB555
|
||||
tmp |= 0x80000000ULL | ((fieldB & 0xF800000000000000ULL) >> 33) | ((fieldB & 0xF8000000000000ULL) >> 30) | ((fieldB & 0xF80000000000ULL) >> 27);
|
||||
else
|
||||
// Tranlucid pixel, so set MSB to 0 and encode colors in ARGB3444
|
||||
tmp |= ((fieldB & 0xE000000000ULL) >> 9) | ((fieldB & 0xF000000000000000ULL) >> 36) | ((fieldB & 0xF0000000000000ULL) >> 32) | ((fieldB & 0xF00000000000ULL) >> 28);
|
||||
|
||||
if ((fieldB & 0xE0ULL) == 0xE0ULL)
|
||||
// Opaque pixel, so set MSB to 1 and encode colors in RGB555
|
||||
tmp |= 0x8000ULL | ((fieldB & 0xF8000000ULL) >> 17) | ((fieldB & 0xF80000ULL) >> 14) | ((fieldB & 0xF800ULL) >> 11);
|
||||
else
|
||||
// Tranlucid pixel, so set MSB to 0 and encode colors in ARGB3444
|
||||
tmp |= ((fieldB & 0xE0ULL) << 7) | ((fieldB & 0xF0000000ULL) >> 20) | ((fieldB & 0xF00000ULL) >> 16) | ((fieldB & 0xF000ULL) >> 12);
|
||||
((PNGU_u64 *) buffer)[blockbase+1] = tmp;
|
||||
|
||||
fieldA = *((PNGU_u64 *)(ctx->row_pointers[y4+2]+x16));
|
||||
fieldB = *((PNGU_u64 *)(ctx->row_pointers[y4+2]+x16+8));
|
||||
if ((fieldA & 0xE000000000ULL) == 0xE000000000ULL)
|
||||
// Opaque pixel, so set MSB to 1 and encode colors in RGB555
|
||||
tmp = 0x8000000000000000ULL | ((fieldA & 0xF800000000000000ULL) >> 1) | ((fieldA & 0xF8000000000000ULL) << 2) | ((fieldA & 0xF80000000000ULL) << 5);
|
||||
else
|
||||
// Tranlucid pixel, so set MSB to 0 and encode colors in ARGB3444
|
||||
tmp = ((fieldA & 0xE000000000ULL) << 23) | ((fieldA & 0xF000000000000000ULL) >> 4) | (fieldA & 0xF0000000000000ULL) | ((fieldA & 0xF00000000000ULL) << 4);
|
||||
|
||||
if ((fieldA & 0xE0ULL) == 0xE0ULL)
|
||||
// Opaque pixel, so set MSB to 1 and encode colors in RGB555
|
||||
tmp |= 0x800000000000ULL | ((fieldA & 0xF8000000ULL) << 15) | ((fieldA & 0xF80000ULL) << 18) | ((fieldA & 0xF800ULL) << 21);
|
||||
else
|
||||
// Tranlucid pixel, so set MSB to 0 and encode colors in ARGB3444
|
||||
tmp |= ((fieldA & 0xE0ULL) << 39) | ((fieldA & 0xF0000000ULL) << 12) | ((fieldA & 0xF00000ULL) << 16) | ((fieldA & 0xF000ULL) << 20);
|
||||
|
||||
if ((fieldB & 0xE000000000ULL) == 0xE000000000ULL)
|
||||
// Opaque pixel, so set MSB to 1 and encode colors in RGB555
|
||||
tmp |= 0x80000000ULL | ((fieldB & 0xF800000000000000ULL) >> 33) | ((fieldB & 0xF8000000000000ULL) >> 30) | ((fieldB & 0xF80000000000ULL) >> 27);
|
||||
else
|
||||
// Tranlucid pixel, so set MSB to 0 and encode colors in ARGB3444
|
||||
tmp |= ((fieldB & 0xE000000000ULL) >> 9) | ((fieldB & 0xF000000000000000ULL) >> 36) | ((fieldB & 0xF0000000000000ULL) >> 32) | ((fieldB & 0xF00000000000ULL) >> 28);
|
||||
|
||||
if ((fieldB & 0xE0ULL) == 0xE0ULL)
|
||||
// Opaque pixel, so set MSB to 1 and encode colors in RGB555
|
||||
tmp |= 0x8000ULL | ((fieldB & 0xF8000000ULL) >> 17) | ((fieldB & 0xF80000ULL) >> 14) | ((fieldB & 0xF800ULL) >> 11);
|
||||
else
|
||||
// Tranlucid pixel, so set MSB to 0 and encode colors in ARGB3444
|
||||
tmp |= ((fieldB & 0xE0ULL) << 7) | ((fieldB & 0xF0000000ULL) >> 20) | ((fieldB & 0xF00000ULL) >> 16) | ((fieldB & 0xF000ULL) >> 12);
|
||||
((PNGU_u64 *) buffer)[blockbase+2] = tmp;
|
||||
|
||||
fieldA = *((PNGU_u64 *)(ctx->row_pointers[y4+3]+x16));
|
||||
fieldB = *((PNGU_u64 *)(ctx->row_pointers[y4+3]+x16+8));
|
||||
if ((fieldA & 0xE000000000ULL) == 0xE000000000ULL)
|
||||
// Opaque pixel, so set MSB to 1 and encode colors in RGB555
|
||||
tmp = 0x8000000000000000ULL | ((fieldA & 0xF800000000000000ULL) >> 1) | ((fieldA & 0xF8000000000000ULL) << 2) | ((fieldA & 0xF80000000000ULL) << 5);
|
||||
else
|
||||
// Tranlucid pixel, so set MSB to 0 and encode colors in ARGB3444
|
||||
tmp = ((fieldA & 0xE000000000ULL) << 23) | ((fieldA & 0xF000000000000000ULL) >> 4) | (fieldA & 0xF0000000000000ULL) | ((fieldA & 0xF00000000000ULL) << 4);
|
||||
|
||||
if ((fieldA & 0xE0ULL) == 0xE0ULL)
|
||||
// Opaque pixel, so set MSB to 1 and encode colors in RGB555
|
||||
tmp |= 0x800000000000ULL | ((fieldA & 0xF8000000ULL) << 15) | ((fieldA & 0xF80000ULL) << 18) | ((fieldA & 0xF800ULL) << 21);
|
||||
else
|
||||
// Tranlucid pixel, so set MSB to 0 and encode colors in ARGB3444
|
||||
tmp |= ((fieldA & 0xE0ULL) << 39) | ((fieldA & 0xF0000000ULL) << 12) | ((fieldA & 0xF00000ULL) << 16) | ((fieldA & 0xF000ULL) << 20);
|
||||
|
||||
if ((fieldB & 0xE000000000ULL) == 0xE000000000ULL)
|
||||
// Opaque pixel, so set MSB to 1 and encode colors in RGB555
|
||||
tmp |= 0x80000000ULL | ((fieldB & 0xF800000000000000ULL) >> 33) | ((fieldB & 0xF8000000000000ULL) >> 30) | ((fieldB & 0xF80000000000ULL) >> 27);
|
||||
else
|
||||
// Tranlucid pixel, so set MSB to 0 and encode colors in ARGB3444
|
||||
tmp |= ((fieldB & 0xE000000000ULL) >> 9) | ((fieldB & 0xF000000000000000ULL) >> 36) | ((fieldB & 0xF0000000000000ULL) >> 32) | ((fieldB & 0xF00000000000ULL) >> 28);
|
||||
|
||||
if ((fieldB & 0xE0ULL) == 0xE0ULL)
|
||||
// Opaque pixel, so set MSB to 1 and encode colors in RGB555
|
||||
tmp |= 0x8000ULL | ((fieldB & 0xF8000000ULL) >> 17) | ((fieldB & 0xF80000ULL) >> 14) | ((fieldB & 0xF800ULL) >> 11);
|
||||
else
|
||||
// Tranlucid pixel, so set MSB to 0 and encode colors in ARGB3444
|
||||
tmp |= ((fieldB & 0xE0ULL) << 7) | ((fieldB & 0xF0000000ULL) >> 20) | ((fieldB & 0xF00000ULL) >> 16) | ((fieldB & 0xF000ULL) >> 12);
|
||||
|
||||
((PNGU_u64 *) buffer)[blockbase+3] = tmp;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// No alpha channel present, copy image to the output buffer
|
||||
default_alpha = (default_alpha >> 5);
|
||||
if (default_alpha == 7)
|
||||
{
|
||||
// The user wants an opaque texture, so set MSB to 1 and encode colors in RGB555
|
||||
alphaMask = 0x8000800080008000ULL;
|
||||
|
||||
for (y = 0; y < qheight; y++)
|
||||
for (x = 0; x < qwidth; x++)
|
||||
{
|
||||
int blockbase = (y * qwidth + x) << 2;
|
||||
|
||||
PNGU_u32 y4 = y << 2;
|
||||
PNGU_u32 x12 = x * 12;
|
||||
|
||||
PNGU_u64 field64 = *((PNGU_u64 *)(ctx->row_pointers[y4]+x12));
|
||||
PNGU_u64 field32 = (PNGU_u64) *((PNGU_u32 *)(ctx->row_pointers[y4]+x12+8));
|
||||
((PNGU_u64 *) buffer)[blockbase] =
|
||||
alphaMask | ((field64 & 0xF800000000000000ULL) >> 1) | ((field64 & 0xF8000000000000ULL) << 2) |
|
||||
((field64 & 0xF80000000000ULL) << 5) | ((field64 & 0xF800000000ULL) << 7) | ((field64 & 0xF8000000ULL) << 10) |
|
||||
((field64 & 0xF80000ULL) << 13) | ((field64 & 0xF800ULL) << 15) | ((field64 & 0xF8ULL) << 18) |
|
||||
((field32 & 0xF8000000ULL) >> 11) | ((field32 & 0xF80000ULL) >> 9) | ((field32 & 0xF800ULL) >> 6) | ((field32 & 0xF8ULL) >> 3);
|
||||
|
||||
field64 = *((PNGU_u64 *)(ctx->row_pointers[y4+1]+x12));
|
||||
field32 = (PNGU_u64) *((PNGU_u32 *)(ctx->row_pointers[y4+1]+x12+8));
|
||||
((PNGU_u64 *) buffer)[blockbase+1] =
|
||||
alphaMask | ((field64 & 0xF800000000000000ULL) >> 1) | ((field64 & 0xF8000000000000ULL) << 2) |
|
||||
((field64 & 0xF80000000000ULL) << 5) | ((field64 & 0xF800000000ULL) << 7) | ((field64 & 0xF8000000ULL) << 10) |
|
||||
((field64 & 0xF80000ULL) << 13) | ((field64 & 0xF800ULL) << 15) | ((field64 & 0xF8ULL) << 18) |
|
||||
((field32 & 0xF8000000ULL) >> 11) | ((field32 & 0xF80000ULL) >> 9) | ((field32 & 0xF800ULL) >> 6) | ((field32 & 0xF8ULL) >> 3);
|
||||
|
||||
field64 = *((PNGU_u64 *)(ctx->row_pointers[y4+2]+x12));
|
||||
field32 = (PNGU_u64) *((PNGU_u32 *)(ctx->row_pointers[y4+2]+x12+8));
|
||||
((PNGU_u64 *) buffer)[blockbase+2] =
|
||||
alphaMask | ((field64 & 0xF800000000000000ULL) >> 1) | ((field64 & 0xF8000000000000ULL) << 2) |
|
||||
((field64 & 0xF80000000000ULL) << 5) | ((field64 & 0xF800000000ULL) << 7) | ((field64 & 0xF8000000ULL) << 10) |
|
||||
((field64 & 0xF80000ULL) << 13) | ((field64 & 0xF800ULL) << 15) | ((field64 & 0xF8ULL) << 18) |
|
||||
((field32 & 0xF8000000ULL) >> 11) | ((field32 & 0xF80000ULL) >> 9) | ((field32 & 0xF800ULL) >> 6) | ((field32 & 0xF8ULL) >> 3);
|
||||
|
||||
field64 = *((PNGU_u64 *)(ctx->row_pointers[y4+3]+x12));
|
||||
field32 = (PNGU_u64) *((PNGU_u32 *)(ctx->row_pointers[y4+3]+x12+8));
|
||||
((PNGU_u64 *) buffer)[blockbase+3] =
|
||||
alphaMask | ((field64 & 0xF800000000000000ULL) >> 1) | ((field64 & 0xF8000000000000ULL) << 2) |
|
||||
((field64 & 0xF80000000000ULL) << 5) | ((field64 & 0xF800000000ULL) << 7) | ((field64 & 0xF8000000ULL) << 10) |
|
||||
((field64 & 0xF80000ULL) << 13) | ((field64 & 0xF800ULL) << 15) | ((field64 & 0xF8ULL) << 18) |
|
||||
((field32 & 0xF8000000ULL) >> 11) | ((field32 & 0xF80000ULL) >> 9) | ((field32 & 0xF800ULL) >> 6) | ((field32 & 0xF8ULL) >> 3);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// The user wants a translucid texture, so set MSB to 0 and encode colors in ARGB3444
|
||||
default_alpha = (default_alpha << 4);
|
||||
alphaMask = (((PNGU_u64) default_alpha) << 56) | (((PNGU_u64) default_alpha) << 40) |
|
||||
(((PNGU_u64) default_alpha) << 24) | (((PNGU_u64) default_alpha) << 8);
|
||||
|
||||
for (y = 0; y < qheight; y++)
|
||||
for (x = 0; x < qwidth; x++)
|
||||
{
|
||||
int blockbase = (y * qwidth + x) << 2;
|
||||
|
||||
PNGU_u32 y4 = y << 2;
|
||||
PNGU_u32 x12 = x * 12;
|
||||
|
||||
PNGU_u64 field64 = *((PNGU_u64 *)(ctx->row_pointers[y4]+x12));
|
||||
PNGU_u64 field32 = (PNGU_u64) *((PNGU_u32 *)(ctx->row_pointers[y4]+x12+8));
|
||||
((PNGU_u64 *) buffer)[blockbase] =
|
||||
alphaMask | ((field64 & 0xF000000000000000ULL) >> 4) | (field64 & 0xF0000000000000ULL) | ((field64 & 0xF00000000000ULL) << 4) |
|
||||
((field64 & 0xF000000000ULL) << 4) | ((field64 & 0xF0000000ULL) << 8) | ((field64 & 0xF00000ULL) << 12) |
|
||||
((field64 & 0xF000ULL) << 12) | ((field64 & 0xF0ULL) << 16) | ((field32 & 0xF0000000ULL) >> 12) |
|
||||
((field32 & 0xF00000ULL) >> 12) | ((field32 & 0xF000ULL) >> 8) | ((field32 & 0xF0ULL) >> 4);
|
||||
|
||||
field64 = *((PNGU_u64 *)(ctx->row_pointers[y4+1]+x12));
|
||||
field32 = (PNGU_u64) *((PNGU_u32 *)(ctx->row_pointers[y4+1]+x12+8));
|
||||
((PNGU_u64 *) buffer)[blockbase+1] =
|
||||
alphaMask | ((field64 & 0xF000000000000000ULL) >> 4) | (field64 & 0xF0000000000000ULL) | ((field64 & 0xF00000000000ULL) << 4) |
|
||||
((field64 & 0xF000000000ULL) << 4) | ((field64 & 0xF0000000ULL) << 8) | ((field64 & 0xF00000ULL) << 12) |
|
||||
((field64 & 0xF000ULL) << 12) | ((field64 & 0xF0ULL) << 16) | ((field32 & 0xF0000000ULL) >> 12) |
|
||||
((field32 & 0xF00000ULL) >> 12) | ((field32 & 0xF000ULL) >> 8) | ((field32 & 0xF0ULL) >> 4);
|
||||
|
||||
field64 = *((PNGU_u64 *)(ctx->row_pointers[y4+2]+x12));
|
||||
field32 = (PNGU_u64) *((PNGU_u32 *)(ctx->row_pointers[y4+2]+x12+8));
|
||||
((PNGU_u64 *) buffer)[blockbase+2] =
|
||||
alphaMask | ((field64 & 0xF000000000000000ULL) >> 4) | (field64 & 0xF0000000000000ULL) | ((field64 & 0xF00000000000ULL) << 4) |
|
||||
((field64 & 0xF000000000ULL) << 4) | ((field64 & 0xF0000000ULL) << 8) | ((field64 & 0xF00000ULL) << 12) |
|
||||
((field64 & 0xF000ULL) << 12) | ((field64 & 0xF0ULL) << 16) | ((field32 & 0xF0000000ULL) >> 12) |
|
||||
((field32 & 0xF00000ULL) >> 12) | ((field32 & 0xF000ULL) >> 8) | ((field32 & 0xF0ULL) >> 4);
|
||||
|
||||
field64 = *((PNGU_u64 *)(ctx->row_pointers[y4+3]+x12));
|
||||
field32 = (PNGU_u64) *((PNGU_u32 *)(ctx->row_pointers[y4+3]+x12+8));
|
||||
((PNGU_u64 *) buffer)[blockbase+3] =
|
||||
alphaMask | ((field64 & 0xF000000000000000ULL) >> 4) | (field64 & 0xF0000000000000ULL) | ((field64 & 0xF00000000000ULL) << 4) |
|
||||
((field64 & 0xF000000000ULL) << 4) | ((field64 & 0xF0000000ULL) << 8) | ((field64 & 0xF00000ULL) << 12) |
|
||||
((field64 & 0xF000ULL) << 12) | ((field64 & 0xF0ULL) << 16) | ((field32 & 0xF0000000ULL) >> 12) |
|
||||
((field32 & 0xF00000ULL) >> 12) | ((field32 & 0xF000ULL) >> 8) | ((field32 & 0xF0ULL) >> 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Free resources
|
||||
free (ctx->img_data);
|
||||
free (ctx->row_pointers);
|
||||
|
||||
// Success
|
||||
return PNGU_OK;
|
||||
}
|
||||
|
||||
int PNGU_DecodeTo4x4RGBA8 (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *buffer, PNGU_u8 default_alpha)
|
||||
{
|
||||
int result;
|
||||
@ -694,122 +264,6 @@ int PNGU_DecodeTo4x4RGBA8 (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *bu
|
||||
return PNGU_OK;
|
||||
}
|
||||
|
||||
int PNGU_EncodeFromYCbYCr (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *buffer, PNGU_u32 stride)
|
||||
{
|
||||
png_uint_32 rowbytes;
|
||||
PNGU_u32 x, y, buffWidth;
|
||||
|
||||
// Erase from the context any readed info
|
||||
pngu_free_info (ctx);
|
||||
ctx->propRead = 0;
|
||||
|
||||
// Check if the user has selected a file to write the image
|
||||
if (ctx->source == PNGU_SOURCE_BUFFER);
|
||||
|
||||
else if (ctx->source == PNGU_SOURCE_DEVICE)
|
||||
{
|
||||
// Open file
|
||||
if (!(ctx->fd = fopen (ctx->filename, "wb")))
|
||||
return PNGU_CANT_OPEN_FILE;
|
||||
}
|
||||
|
||||
else
|
||||
return PNGU_NO_FILE_SELECTED;
|
||||
|
||||
// Allocation of libpng structs
|
||||
ctx->png_ptr = png_create_write_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
|
||||
if (!(ctx->png_ptr))
|
||||
{
|
||||
if (ctx->source == PNGU_SOURCE_DEVICE)
|
||||
fclose (ctx->fd);
|
||||
return PNGU_LIB_ERROR;
|
||||
}
|
||||
|
||||
ctx->info_ptr = png_create_info_struct (ctx->png_ptr);
|
||||
if (!(ctx->info_ptr))
|
||||
{
|
||||
png_destroy_write_struct (&(ctx->png_ptr), (png_infopp)NULL);
|
||||
if (ctx->source == PNGU_SOURCE_DEVICE)
|
||||
fclose (ctx->fd);
|
||||
return PNGU_LIB_ERROR;
|
||||
}
|
||||
|
||||
if (ctx->source == PNGU_SOURCE_BUFFER)
|
||||
{
|
||||
// Installation of our custom data writer function
|
||||
ctx->cursor = 0;
|
||||
png_set_write_fn (ctx->png_ptr, ctx, pngu_write_data_to_buffer, pngu_flush_data_to_buffer);
|
||||
}
|
||||
else if (ctx->source == PNGU_SOURCE_DEVICE)
|
||||
{
|
||||
// Default data writer uses function fwrite, so it needs to use our FILE*
|
||||
png_init_io (ctx->png_ptr, ctx->fd);
|
||||
}
|
||||
|
||||
// Setup output file properties
|
||||
png_set_IHDR (ctx->png_ptr, ctx->info_ptr, width, height, 8, PNG_COLOR_TYPE_RGB,
|
||||
PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
|
||||
|
||||
// Allocate memory to store the image in RGB format
|
||||
rowbytes = width * 3;
|
||||
if (rowbytes % 4)
|
||||
rowbytes = ((rowbytes >> 2) + 1) << 2;
|
||||
|
||||
ctx->img_data = malloc (rowbytes * height);
|
||||
if (!ctx->img_data)
|
||||
{
|
||||
png_destroy_write_struct (&(ctx->png_ptr), (png_infopp)NULL);
|
||||
if (ctx->source == PNGU_SOURCE_DEVICE)
|
||||
fclose (ctx->fd);
|
||||
return PNGU_LIB_ERROR;
|
||||
}
|
||||
|
||||
ctx->row_pointers = malloc (sizeof (png_bytep) * height);
|
||||
if (!ctx->row_pointers)
|
||||
{
|
||||
png_destroy_write_struct (&(ctx->png_ptr), (png_infopp)NULL);
|
||||
if (ctx->source == PNGU_SOURCE_DEVICE)
|
||||
fclose (ctx->fd);
|
||||
return PNGU_LIB_ERROR;
|
||||
}
|
||||
|
||||
// Encode YCbYCr image into RGB8 format
|
||||
buffWidth = (width + stride) >> 1;
|
||||
PNGU_u32 wid2 = width >> 1;
|
||||
for (y = 0; y < height; y++)
|
||||
{
|
||||
ctx->row_pointers[y] = ctx->img_data + (y * rowbytes);
|
||||
|
||||
for (x = 0; x < wid2; ++x)
|
||||
{
|
||||
PNGU_u32 x6 = x*6;
|
||||
PNGU_YCbYCr_TO_RGB8 ( ((PNGU_u32 *)buffer)[y*buffWidth+x],
|
||||
((PNGU_u8 *) ctx->row_pointers[y]+x6), ((PNGU_u8 *) ctx->row_pointers[y]+x6+1),
|
||||
((PNGU_u8 *) ctx->row_pointers[y]+x6+2), ((PNGU_u8 *) ctx->row_pointers[y]+x6+3),
|
||||
((PNGU_u8 *) ctx->row_pointers[y]+x6+4), ((PNGU_u8 *) ctx->row_pointers[y]+x6+5) );
|
||||
}
|
||||
}
|
||||
|
||||
// Tell libpng where is our image data
|
||||
png_set_rows (ctx->png_ptr, ctx->info_ptr, ctx->row_pointers);
|
||||
|
||||
// Write file header and image data
|
||||
png_write_png (ctx->png_ptr, ctx->info_ptr, PNG_TRANSFORM_IDENTITY, NULL);
|
||||
|
||||
// Tell libpng we have no more data to write
|
||||
png_write_end (ctx->png_ptr, (png_infop) NULL);
|
||||
|
||||
// Free resources
|
||||
free (ctx->img_data);
|
||||
free (ctx->row_pointers);
|
||||
png_destroy_write_struct (&(ctx->png_ptr), &(ctx->info_ptr));
|
||||
if (ctx->source == PNGU_SOURCE_DEVICE)
|
||||
fclose (ctx->fd);
|
||||
|
||||
// Success
|
||||
return PNGU_OK;
|
||||
}
|
||||
|
||||
int PNGU_EncodeFromRGB (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *buffer, PNGU_u32 stride)
|
||||
{
|
||||
png_uint_32 rowbytes;
|
||||
@ -950,46 +404,6 @@ int PNGU_EncodeFromGXTexture (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void
|
||||
return res;
|
||||
}
|
||||
|
||||
// This function is taken from a libogc example
|
||||
PNGU_u32 PNGU_RGB8_TO_YCbYCr (PNGU_u8 r1, PNGU_u8 g1, PNGU_u8 b1, PNGU_u8 r2, PNGU_u8 g2, PNGU_u8 b2)
|
||||
{
|
||||
PNGU_u32 y1, cb1, cr1, y2, cb2, cr2, cb, cr;
|
||||
|
||||
y1 = (299 * r1 + 587 * g1 + 114 * b1) / 1000;
|
||||
cb1 = (-16874 * r1 - 33126 * g1 + 50000 * b1 + 12800000) / 100000;
|
||||
cr1 = (50000 * r1 - 41869 * g1 - 8131 * b1 + 12800000) / 100000;
|
||||
|
||||
y2 = (299 * r2 + 587 * g2 + 114 * b2) / 1000;
|
||||
cb2 = (-16874 * r2 - 33126 * g2 + 50000 * b2 + 12800000) / 100000;
|
||||
cr2 = (50000 * r2 - 41869 * g2 - 8131 * b2 + 12800000) / 100000;
|
||||
|
||||
cb = (cb1 + cb2) >> 1;
|
||||
cr = (cr1 + cr2) >> 1;
|
||||
|
||||
return (PNGU_u32) ((y1 << 24) | (cb << 16) | (y2 << 8) | cr);
|
||||
}
|
||||
|
||||
void PNGU_YCbYCr_TO_RGB8 (PNGU_u32 ycbycr, PNGU_u8 *r1, PNGU_u8 *g1, PNGU_u8 *b1, PNGU_u8 *r2, PNGU_u8 *g2, PNGU_u8 *b2)
|
||||
{
|
||||
PNGU_u8 *val = (PNGU_u8 *) &ycbycr;
|
||||
|
||||
float val1 = (float)((int)(val[1]) - 128);
|
||||
float val3 = (float)((int)(val[3]) - 128);
|
||||
|
||||
int r = (int)(1.371f * val3);
|
||||
int g = (int)(- 0.698f * val3 - 0.336f * val1);
|
||||
int b = (int)(1.732f * val1);
|
||||
|
||||
*r1 = pngu_clamp (val[0] + r, 0, 255);
|
||||
*g1 = pngu_clamp (val[0] + g, 0, 255);
|
||||
*b1 = pngu_clamp (val[0] + b, 0, 255);
|
||||
|
||||
*r2 = pngu_clamp (val[2] + r, 0, 255);
|
||||
*g2 = pngu_clamp (val[2] + g, 0, 255);
|
||||
*b2 = pngu_clamp (val[2] + b, 0, 255);
|
||||
}
|
||||
|
||||
|
||||
int pngu_info (IMGCTX ctx)
|
||||
{
|
||||
png_byte magic[8];
|
||||
@ -1265,7 +679,6 @@ int pngu_decode (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, PNGU_u32 stripAlph
|
||||
return PNGU_OK;
|
||||
}
|
||||
|
||||
|
||||
void pngu_free_info (IMGCTX ctx)
|
||||
{
|
||||
if (ctx->infoRead)
|
||||
@ -1279,7 +692,6 @@ void pngu_free_info (IMGCTX ctx)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Custom data provider function used for reading from memory buffers.
|
||||
void pngu_read_data_from_buffer (png_structp png_ptr, png_bytep data, png_size_t length)
|
||||
{
|
||||
@ -1288,7 +700,6 @@ void pngu_read_data_from_buffer (png_structp png_ptr, png_bytep data, png_size_t
|
||||
ctx->cursor += length;
|
||||
}
|
||||
|
||||
|
||||
// Custom data writer function used for writing to memory buffers.
|
||||
void pngu_write_data_to_buffer (png_structp png_ptr, png_bytep data, png_size_t length)
|
||||
{
|
||||
@ -1297,14 +708,12 @@ void pngu_write_data_to_buffer (png_structp png_ptr, png_bytep data, png_size_t
|
||||
ctx->cursor += length;
|
||||
}
|
||||
|
||||
|
||||
// Custom data flusher function used for writing to memory buffers.
|
||||
void pngu_flush_data_to_buffer (png_structp png_ptr)
|
||||
{
|
||||
// Nothing to do here
|
||||
}
|
||||
|
||||
|
||||
// Function used in YCbYCr to RGB decoding
|
||||
int pngu_clamp (int value, int min, int max)
|
||||
{
|
||||
|
@ -66,26 +66,6 @@ typedef struct
|
||||
struct _IMGCTX;
|
||||
typedef struct _IMGCTX *IMGCTX;
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* Pixel conversion *
|
||||
****************************************************************************/
|
||||
|
||||
// Macro to convert RGB8 values to RGB565
|
||||
#define PNGU_RGB8_TO_RGB565(r,g,b) ( ((((PNGU_u16) r) & 0xF8U) << 8) | ((((PNGU_u16) g) & 0xFCU) << 3) | (((PNGU_u16) b) >> 3) )
|
||||
|
||||
// Macro to convert RGBA8 values to RGB5A3
|
||||
#define PNGU_RGB8_TO_RGB5A3(r,g,b,a) (PNGU_u16) (((a & 0xE0U) == 0xE0U) ? \
|
||||
(0x8000U | ((((PNGU_u16) r) & 0xF8U) << 7) | ((((PNGU_u16) g) & 0xF8U) << 2) | (((PNGU_u16) b) >> 3)) : \
|
||||
(((((PNGU_u16) a) & 0xE0U) << 7) | ((((PNGU_u16) r) & 0xF0U) << 4) | (((PNGU_u16) g) & 0xF0U) | ((((PNGU_u16) b) & 0xF0U) >> 4)))
|
||||
|
||||
// Function to convert two RGB8 values to YCbYCr
|
||||
PNGU_u32 PNGU_RGB8_TO_YCbYCr (PNGU_u8 r1, PNGU_u8 g1, PNGU_u8 b1, PNGU_u8 r2, PNGU_u8 g2, PNGU_u8 b2);
|
||||
|
||||
// Function to convert an YCbYCr to two RGB8 values.
|
||||
void PNGU_YCbYCr_TO_RGB8 (PNGU_u32 ycbycr, PNGU_u8 *r1, PNGU_u8 *g1, PNGU_u8 *b1, PNGU_u8 *r2, PNGU_u8 *g2, PNGU_u8 *b2);
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* Image context handling *
|
||||
****************************************************************************/
|
||||
@ -107,67 +87,17 @@ void PNGU_ReleaseImageContext (IMGCTX ctx);
|
||||
// Retrieves info from selected PNG file, including image dimensions, color format, background and transparency colors.
|
||||
int PNGU_GetImageProperties (IMGCTX ctx, PNGUPROP *fileproperties);
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* Image conversion *
|
||||
****************************************************************************/
|
||||
|
||||
// Expands selected image into an YCbYCr buffer. You need to specify context, image dimensions,
|
||||
// destination address and stride in pixels (stride = buffer width - image width).
|
||||
int PNGU_DecodeToYCbYCr (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *buffer, PNGU_u32 stride);
|
||||
|
||||
// Macro for decoding an image inside a buffer at given coordinates.
|
||||
#define PNGU_DECODE_TO_COORDS_YCbYCr(ctx,coordX,coordY,imgWidth,imgHeight,bufferWidth,bufferHeight,buffer) \
|
||||
\
|
||||
PNGU_DecodeToYCbYCr (ctx, imgWidth, imgHeight, ((void *) buffer) + (coordY) * (bufferWidth) * 2 + \
|
||||
(coordX) * 2, (bufferWidth) - (imgWidth))
|
||||
|
||||
// Expands selected image into a linear RGB565 buffer. You need to specify context, image dimensions,
|
||||
// destination address and stride in pixels (stride = buffer width - image width).
|
||||
int PNGU_DecodeToRGB565 (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *buffer, PNGU_u32 stride);
|
||||
|
||||
// Macro for decoding an image inside a buffer at given coordinates.
|
||||
#define PNGU_DECODE_TO_COORDS_RGB565(ctx,coordX,coordY,imgWidth,imgHeight,bufferWidth,bufferHeight,buffer) \
|
||||
\
|
||||
PNGU_DecodeToRGB565 (ctx, imgWidth, imgHeight, ((void *) buffer) + (coordY) * (bufferWidth) * 2 + \
|
||||
(coordX) * 2, (bufferWidth) - (imgWidth))
|
||||
|
||||
// Expands selected image into a linear RGBA8 buffer. You need to specify context, image dimensions,
|
||||
// destination address, stride in pixels and default alpha value, which is used if the source image
|
||||
// doesn't have an alpha channel.
|
||||
int PNGU_DecodeToRGBA8 (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *buffer, PNGU_u32 stride, PNGU_u8 default_alpha);
|
||||
|
||||
// Macro for decoding an image inside a buffer at given coordinates.
|
||||
#define PNGU_DECODE_TO_COORDS_RGBA8(ctx,coordX,coordY,imgWidth,imgHeight,default_alpha,bufferWidth,bufferHeight,buffer) \
|
||||
\
|
||||
PNGU_DecodeToRGBA8 (ctx, imgWidth, imgHeight, ((void *) buffer) + (coordY) * (bufferWidth) * 2 + \
|
||||
(coordX) * 2, (bufferWidth) - (imgWidth), default_alpha)
|
||||
|
||||
// Expands selected image into a 4x4 tiled RGB565 buffer. You need to specify context, image dimensions
|
||||
// and destination address.
|
||||
int PNGU_DecodeTo4x4RGB565 (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *buffer);
|
||||
|
||||
// Expands selected image into a 4x4 tiled RGB5A3 buffer. You need to specify context, image dimensions,
|
||||
// destination address and default alpha value, which is used if the source image doesn't have an alpha channel.
|
||||
int PNGU_DecodeTo4x4RGB5A3 (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *buffer, PNGU_u8 default_alpha);
|
||||
|
||||
// Expands selected image into a 4x4 tiled RGBA8 buffer. You need to specify context, image dimensions,
|
||||
// destination address and default alpha value, which is used if the source image doesn't have an alpha channel.
|
||||
int PNGU_DecodeTo4x4RGBA8 (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *buffer, PNGU_u8 default_alpha);
|
||||
|
||||
// Encodes an YCbYCr image in PNG format and stores it in the selected device or memory buffer. You need to
|
||||
// specify context, image dimensions, destination address and stride in pixels (stride = buffer width - image width).
|
||||
int PNGU_EncodeFromYCbYCr (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *buffer, PNGU_u32 stride);
|
||||
|
||||
int PNGU_EncodeFromRGB (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *buffer, PNGU_u32 stride);
|
||||
int PNGU_EncodeFromGXTexture (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *buffer, PNGU_u32 stride);
|
||||
|
||||
// Macro for encoding an image stored into an YCbYCr buffer at given coordinates.
|
||||
#define PNGU_ENCODE_TO_COORDS_YCbYCr(ctx,coordX,coordY,imgWidth,imgHeight,bufferWidth,bufferHeight,buffer) \
|
||||
\
|
||||
PNGU_EncodeFromYCbYCr (ctx, imgWidth, imgHeight, ((void *) buffer) + (coordY) * (bufferWidth) * 2 + \
|
||||
(coordX) * 2, (bufferWidth) - (imgWidth))
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user