mirror of
https://github.com/GRRLIB/GRRLIB.git
synced 2024-11-22 23:12:21 +00:00
[ADD] Added GRRLIB_FBReadPixel to read pixels directly from the FB.
[CHG] Optimized PNGU's YCbCr algorithm, allowing a full spectrum of RGB colors (0 - 255).
This commit is contained in:
parent
a9c6b7043f
commit
b120658463
3 changed files with 75 additions and 100 deletions
|
@ -24,7 +24,6 @@ GXRModeObj *rmode;
|
||||||
void *gp_fifo = NULL;
|
void *gp_fifo = NULL;
|
||||||
|
|
||||||
static GRRLIB_drawSettings GRRLIB_Settings;
|
static GRRLIB_drawSettings GRRLIB_Settings;
|
||||||
static GRRLIB_linkedList *GRRLIB_ListImages;
|
|
||||||
|
|
||||||
static void RawTo4x4RGBA(const unsigned char *src, void *dst, const unsigned int width, const unsigned int height);
|
static void RawTo4x4RGBA(const unsigned char *src, void *dst, const unsigned int width, const unsigned int height);
|
||||||
|
|
||||||
|
@ -315,7 +314,6 @@ GRRLIB_texImg GRRLIB_LoadTexturePNG(const unsigned char my_png[]) {
|
||||||
my_texture.offsetx = 0; my_texture.offsety = 0;
|
my_texture.offsetx = 0; my_texture.offsety = 0;
|
||||||
my_texture.tiledtex = false;
|
my_texture.tiledtex = false;
|
||||||
GRRLIB_SetHandle( &my_texture, 0, 0 );
|
GRRLIB_SetHandle( &my_texture, 0, 0 );
|
||||||
GRRLIB_ListAddTexture( &my_texture );
|
|
||||||
GRRLIB_FlushTex( my_texture );
|
GRRLIB_FlushTex( my_texture );
|
||||||
return my_texture;
|
return my_texture;
|
||||||
}
|
}
|
||||||
|
@ -377,7 +375,6 @@ GRRLIB_texImg GRRLIB_LoadTextureJPG(const unsigned char my_jpg[]) {
|
||||||
my_texture.offsetx = 0; my_texture.offsety = 0;
|
my_texture.offsetx = 0; my_texture.offsety = 0;
|
||||||
my_texture.tiledtex = false;
|
my_texture.tiledtex = false;
|
||||||
GRRLIB_SetHandle( &my_texture, 0, 0 );
|
GRRLIB_SetHandle( &my_texture, 0, 0 );
|
||||||
GRRLIB_ListAddTexture( &my_texture );
|
|
||||||
GRRLIB_FlushTex(my_texture);
|
GRRLIB_FlushTex(my_texture);
|
||||||
return my_texture;
|
return my_texture;
|
||||||
}
|
}
|
||||||
|
@ -1192,7 +1189,6 @@ void GRRLIB_Init() {
|
||||||
|
|
||||||
// Default settings
|
// Default settings
|
||||||
GRRLIB_Settings.antialias = true;
|
GRRLIB_Settings.antialias = true;
|
||||||
GRRLIB_ListImages = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1254,65 +1250,59 @@ bool GRRLIB_ScrShot(const char* File) {
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a GRRLIB texture into the list.
|
* Reads a pixel directly from the FrontBuffer.
|
||||||
* @param img The texture to add.
|
* Since the FB is stored in YCbCr,
|
||||||
|
* @param x The x-coordinate within the FB.
|
||||||
|
* @param y The y-coordinate within the FB.
|
||||||
|
* @param R1 A pointer to a variable receiving the first Red value.
|
||||||
|
* @param G1 A pointer to a variable receiving the first Green value.
|
||||||
|
* @param B1 A pointer to a variable receiving the first Blue value.
|
||||||
|
* @param R2 A pointer to a variable receiving the second Red value.
|
||||||
|
* @param G2 A pointer to a variable receiving the second Green value.
|
||||||
|
* @param B2 A pointer to a variable receiving the second Blue value.
|
||||||
*/
|
*/
|
||||||
void GRRLIB_ListAddTexture( struct GRRLIB_texImg *img ) {
|
void GRRLIB_FBReadPixel(int x, int y, u8 *R1, u8 *G1, u8 *B1, u8* R2, u8 *G2, u8 *B2 ) {
|
||||||
GRRLIB_linkedList *temp = malloc(sizeof(GRRLIB_linkedList));
|
// Position Correction
|
||||||
if (temp == NULL) { return; }
|
if (x > rmode->fbWidth) { x = rmode->fbWidth; }
|
||||||
|
if (x < 0) { x = 0; }
|
||||||
|
if (y > rmode->efbHeight) { y = rmode->efbHeight; }
|
||||||
|
if (y < 0) { y = 0; }
|
||||||
|
x = x / 2; /* FB is storing 2 pixels at once (YCbCr),
|
||||||
|
so we just need half of the width. */
|
||||||
|
|
||||||
temp->next = *&GRRLIB_ListImages;
|
// Preparing FB for reading
|
||||||
temp->texture = img;
|
u32 Buffer = (((u32 *)xfb[fb])[y*(rmode->fbWidth/2)+x]);
|
||||||
temp->Num = 1337;
|
u8 *Colors = (u8 *) &Buffer;
|
||||||
*&GRRLIB_ListImages = temp;
|
|
||||||
|
/** Color channel:
|
||||||
|
Colors[0] = Y1
|
||||||
|
Colors[1] = Cb
|
||||||
|
Colors[2] = Y2
|
||||||
|
Colors[3] = Cr */
|
||||||
|
|
||||||
|
*R1 = GRRLIB_FBClamp( 1.164 * (Colors[0] - 16) + 1.596 * (Colors[3] - 128) );
|
||||||
|
*G1 = GRRLIB_FBClamp( 1.164 * (Colors[0] - 16) - 0.813 * (Colors[3] - 128) - 0.392 * (Colors[1] - 128) );
|
||||||
|
*B1 = GRRLIB_FBClamp( 1.164 * (Colors[0] - 16) + 2.017 * (Colors[1] - 128) );
|
||||||
|
|
||||||
|
*R2 = GRRLIB_FBClamp( 1.164 * (Colors[2] - 16) + 1.596 * (Colors[3] - 128) );
|
||||||
|
*G2 = GRRLIB_FBClamp( 1.164 * (Colors[2] - 16) - 0.813 * (Colors[3] - 128) - 0.392 * (Colors[1] - 128) );
|
||||||
|
*B2 = GRRLIB_FBClamp( 1.164 * (Colors[2] - 16) + 2.017 * (Colors[1] - 128) );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete an list entry containing the pointer of a texture.
|
* A helper function for the YCbCr -> RGB conversion.
|
||||||
* @param img The texture to delete.
|
* Clamps the given value into a range of 0 - 255 and thus preventing an overflow.
|
||||||
|
* @param The value to clamp.
|
||||||
|
* @return Returns a clean, clamped unsigned char.
|
||||||
*/
|
*/
|
||||||
int GRRLIB_ListDelTexture( struct GRRLIB_texImg *img ) {
|
u8 GRRLIB_FBClamp (float Value) {
|
||||||
GRRLIB_linkedList *temp = GRRLIB_ListImages;
|
/* Using float to increase the precision.
|
||||||
|
This makes a full spectrum (0 - 255) possible. */
|
||||||
if (!temp) { return false; } // List is empty.
|
Value = roundf(Value);
|
||||||
while ( temp->next ) {
|
if (Value < 0) {
|
||||||
if (temp->texture == img) { // <- Doesn't really work, need to find another way. :x
|
Value = 0;
|
||||||
return 1337;
|
} else if (Value > 255) {
|
||||||
//free(img->data);
|
Value = 255;
|
||||||
//free(img);
|
|
||||||
//GRRLIB_ListRemove( &temp );
|
|
||||||
//return true;
|
|
||||||
}
|
}
|
||||||
temp = temp->next;
|
return (u8)Value;
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Removes an entry of an Array List.
|
|
||||||
* @param list The pointer to a list.
|
|
||||||
*/
|
|
||||||
void GRRLIB_ListRemove( struct GRRLIB_linkedList **list ) {
|
|
||||||
if (list) {
|
|
||||||
GRRLIB_linkedList *temp = *list;
|
|
||||||
*list = (*list)->next;
|
|
||||||
free(temp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Just for testing purposes.
|
|
||||||
* Loops through all members of an Array List and returns the member count.
|
|
||||||
*/
|
|
||||||
unsigned int GRRLIB_ListGetTextureEntries() {
|
|
||||||
unsigned int cnt = 0;
|
|
||||||
GRRLIB_linkedList *temp = GRRLIB_ListImages;
|
|
||||||
|
|
||||||
if (!temp) { return 0; } // List is empty.
|
|
||||||
while ( temp->next ) {
|
|
||||||
cnt = cnt + 1;
|
|
||||||
temp = temp->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
return cnt;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -84,15 +84,6 @@ typedef struct GRRLIB_bytemapFont {
|
||||||
GRRLIB_bytemapChar *charDef; /**< List of bitmap character definitions. */
|
GRRLIB_bytemapChar *charDef; /**< List of bitmap character definitions. */
|
||||||
} GRRLIB_bytemapFont;
|
} GRRLIB_bytemapFont;
|
||||||
|
|
||||||
/**
|
|
||||||
* Linked List to inherit all members of an GRRLIB struct.
|
|
||||||
*/
|
|
||||||
typedef struct GRRLIB_linkedList {
|
|
||||||
GRRLIB_texImg *texture; /**< GRRLIB Texture. */
|
|
||||||
int Num;
|
|
||||||
struct GRRLIB_linkedList *next; /**< Pointer to next LinkedList. */
|
|
||||||
} GRRLIB_linkedList;
|
|
||||||
|
|
||||||
|
|
||||||
extern Mtx GXmodelView2D;
|
extern Mtx GXmodelView2D;
|
||||||
|
|
||||||
|
@ -166,11 +157,8 @@ void GRRLIB_Exit();
|
||||||
|
|
||||||
bool GRRLIB_ScrShot(const char*);
|
bool GRRLIB_ScrShot(const char*);
|
||||||
|
|
||||||
void GRRLIB_ListAddTexture( struct GRRLIB_texImg *img );
|
void GRRLIB_FBReadPixel(int x, int y, u8 *R1, u8 *G1, u8 *B1, u8* R2, u8 *G2, u8 *B2 );
|
||||||
int GRRLIB_ListDelTexture( struct GRRLIB_texImg *img );
|
u8 GRRLIB_FBClamp (float Value);
|
||||||
void GRRLIB_ListRemove( struct GRRLIB_linkedList **list );
|
|
||||||
unsigned int GRRLIB_ListGetTextureEntries();
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,16 @@
|
||||||
/********************************************************************************************
|
/********************************************************************************************
|
||||||
|
|
||||||
PNGU Version : 0.2a
|
PNGU Version : 0.2b
|
||||||
|
|
||||||
Coder : frontier
|
Coder : frontier
|
||||||
|
YCbCr fix by Xane
|
||||||
|
|
||||||
More info : http://frontier-dev.net
|
More info : http://frontier-dev.net
|
||||||
|
|
||||||
********************************************************************************************/
|
********************************************************************************************/
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
|
#include <math.h>
|
||||||
#include "pngu.h"
|
#include "pngu.h"
|
||||||
#include "../png.h"
|
#include "../png.h"
|
||||||
|
|
||||||
|
@ -25,7 +27,7 @@ void pngu_free_info (IMGCTX ctx);
|
||||||
void pngu_read_data_from_buffer (png_structp png_ptr, png_bytep data, png_size_t length);
|
void pngu_read_data_from_buffer (png_structp png_ptr, png_bytep data, png_size_t length);
|
||||||
void pngu_write_data_to_buffer (png_structp png_ptr, png_bytep data, png_size_t length);
|
void pngu_write_data_to_buffer (png_structp png_ptr, png_bytep data, png_size_t length);
|
||||||
void pngu_flush_data_to_buffer (png_structp png_ptr);
|
void pngu_flush_data_to_buffer (png_structp png_ptr);
|
||||||
int pngu_clamp (int value, int min, int max);
|
int pngu_clamp (float value);
|
||||||
|
|
||||||
|
|
||||||
// PNGU Image context struct
|
// PNGU Image context struct
|
||||||
|
@ -818,20 +820,15 @@ PNGU_u32 PNGU_RGB8_TO_YCbYCr (PNGU_u8 r1, PNGU_u8 g1, PNGU_u8 b1, PNGU_u8 r2, PN
|
||||||
|
|
||||||
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)
|
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;
|
PNGU_u8 *Colors = (PNGU_u8 *) &ycbycr;
|
||||||
int r, g, b;
|
|
||||||
|
|
||||||
r = 1.371f * (val[3] - 128);
|
*r1 = pngu_clamp( 1.164 * (Colors[0] - 16) + 1.596 * (Colors[3] - 128) );
|
||||||
g = - 0.698f * (val[3] - 128) - 0.336f * (val[1] - 128);
|
*g1 = pngu_clamp( 1.164 * (Colors[0] - 16) - 0.813 * (Colors[3] - 128) - 0.392 * (Colors[1] - 128) );
|
||||||
b = 1.732f * (val[1] - 128);
|
*b1 = pngu_clamp( 1.164 * (Colors[0] - 16) + 2.017 * (Colors[1] - 128) );
|
||||||
|
|
||||||
*r1 = pngu_clamp (val[0] + r, 0, 255);
|
*r2 = pngu_clamp( 1.164 * (Colors[2] - 16) + 1.596 * (Colors[3] - 128) );
|
||||||
*g1 = pngu_clamp (val[0] + g, 0, 255);
|
*g2 = pngu_clamp( 1.164 * (Colors[2] - 16) - 0.813 * (Colors[3] - 128) - 0.392 * (Colors[1] - 128) );
|
||||||
*b1 = pngu_clamp (val[0] + b, 0, 255);
|
*b2 = pngu_clamp( 1.164 * (Colors[2] - 16) + 2.017 * (Colors[1] - 128) );
|
||||||
|
|
||||||
*r2 = pngu_clamp (val[2] + r, 0, 255);
|
|
||||||
*g2 = pngu_clamp (val[2] + g, 0, 255);
|
|
||||||
*b2 = pngu_clamp (val[2] + b, 0, 255);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1120,13 +1117,13 @@ void pngu_flush_data_to_buffer (png_structp png_ptr)
|
||||||
|
|
||||||
|
|
||||||
// Function used in YCbYCr to RGB decoding
|
// Function used in YCbYCr to RGB decoding
|
||||||
int pngu_clamp (int value, int min, int max)
|
int pngu_clamp(float Value) {
|
||||||
{
|
Value = roundf(Value);
|
||||||
if (value < min)
|
if (Value < 0) {
|
||||||
value = min;
|
Value = 0;
|
||||||
else if (value > max)
|
} else if (Value > 255) {
|
||||||
value = max;
|
Value = 255;
|
||||||
|
}
|
||||||
return value;
|
return (int)Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue