mirror of
https://github.com/GRRLIB/GRRLIB.git
synced 2024-11-10 10:22:20 +00:00
[CHG] Modify GRRLIB_ScrShot to work with EFB (maybe...)
This commit is contained in:
parent
740a81df7e
commit
10aee9c66b
4 changed files with 170 additions and 6 deletions
|
@ -94,9 +94,9 @@ bool GRRLIB_ScrShot(const char* filename) {
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
|
|
||||||
if ( (pngContext = PNGU_SelectImageFromDevice(filename)) ) {
|
if ( (pngContext = PNGU_SelectImageFromDevice(filename)) ) {
|
||||||
ret = PNGU_EncodeFromYCbYCr( pngContext,
|
ret = PNGU_EncodeFromEFB( pngContext,
|
||||||
rmode->fbWidth, rmode->efbHeight,
|
rmode->fbWidth, rmode->efbHeight,
|
||||||
xfb[fb], 0 );
|
0 );
|
||||||
PNGU_ReleaseImageContext(pngContext);
|
PNGU_ReleaseImageContext(pngContext);
|
||||||
}
|
}
|
||||||
return !ret;
|
return !ret;
|
||||||
|
|
|
@ -43,8 +43,8 @@ void GRRLIB_Screen2Texture (int posx, int posy, GRRLIB_texImg *tex, bool clear)
|
||||||
* Start GX compositing process.
|
* Start GX compositing process.
|
||||||
* @see GRRLIB_CompoEnd
|
* @see GRRLIB_CompoEnd
|
||||||
*/
|
*/
|
||||||
void GRRLIB_CompoStart (void){
|
void GRRLIB_CompoStart (void) {
|
||||||
GX_SetPixelFmt(GX_PF_RGBA6_Z24,GX_ZC_LINEAR);
|
GX_SetPixelFmt(GX_PF_RGBA6_Z24, GX_ZC_LINEAR);
|
||||||
GX_PokeAlphaRead(GX_READ_NONE);
|
GX_PokeAlphaRead(GX_READ_NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,7 +56,7 @@ void GRRLIB_CompoStart (void){
|
||||||
* @param posy top left corner of the grabbed part.
|
* @param posy top left corner of the grabbed part.
|
||||||
* @param tex A pointer to a texture representing the screen or NULL if an error occurs.
|
* @param tex A pointer to a texture representing the screen or NULL if an error occurs.
|
||||||
*/
|
*/
|
||||||
void GRRLIB_CompoEnd(int posx, int posy, GRRLIB_texImg *tex){
|
void GRRLIB_CompoEnd(int posx, int posy, GRRLIB_texImg *tex) {
|
||||||
GRRLIB_Screen2Texture(posx, posy, tex, FALSE);
|
GRRLIB_Screen2Texture(posx, posy, tex, FALSE);
|
||||||
|
|
||||||
GX_SetTexCopySrc(0, 0, rmode->fbWidth, rmode->efbHeight);
|
GX_SetTexCopySrc(0, 0, rmode->fbWidth, rmode->efbHeight);
|
||||||
|
|
|
@ -682,6 +682,166 @@ int PNGU_DecodeTo4x4RGBA8 (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *bu
|
||||||
return PNGU_OK;
|
return PNGU_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Coded by Tantric for libwiigui (http://code.google.com/p/libwiigui)
|
||||||
|
int PNGU_EncodeFromRGB (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *buffer, PNGU_u32 stride)
|
||||||
|
{
|
||||||
|
png_uint_32 rowbytes;
|
||||||
|
PNGU_u32 y;
|
||||||
|
|
||||||
|
// 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 / 4) + 1) * 4; // Add extra padding so each row starts in a 4 byte boundary
|
||||||
|
|
||||||
|
ctx->img_data = malloc(rowbytes * height);
|
||||||
|
memset(ctx->img_data, 0, 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);
|
||||||
|
memset(ctx->row_pointers, 0, 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (y = 0; y < height; y++)
|
||||||
|
{
|
||||||
|
ctx->row_pointers[y] = buffer + (y * rowbytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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 ctx->cursor;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Coded by Tantric for libwiigui (http://code.google.com/p/libwiigui)
|
||||||
|
int PNGU_EncodeFromGXTexture (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *buffer, PNGU_u32 stride)
|
||||||
|
{
|
||||||
|
int x,y,res;
|
||||||
|
unsigned char * ptr = (unsigned char*)buffer;
|
||||||
|
unsigned char * tmpbuffer = (unsigned char *)malloc(width*height*3);
|
||||||
|
memset(tmpbuffer, 0, width*height*3);
|
||||||
|
png_uint_32 offset;
|
||||||
|
|
||||||
|
for(y=0; y < height; y++)
|
||||||
|
{
|
||||||
|
for(x=0; x < width; x++)
|
||||||
|
{
|
||||||
|
offset = (((y >> 2)<<4)*width) + ((x >> 2)<<6) + (((y%4 << 2) + x%4 ) << 1);
|
||||||
|
|
||||||
|
tmpbuffer[y*640*3+x*3] = ptr[offset+1]; // R
|
||||||
|
tmpbuffer[y*640*3+x*3+1] = ptr[offset+32]; // G
|
||||||
|
tmpbuffer[y*640*3+x*3+2] = ptr[offset+33]; // B
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
res = PNGU_EncodeFromRGB (ctx, width, height, tmpbuffer, stride);
|
||||||
|
free(tmpbuffer);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Coded by Crayon for GRRLIB (http://code.google.com/p/grrlib)
|
||||||
|
int PNGU_EncodeFromEFB (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, PNGU_u32 stride)
|
||||||
|
{
|
||||||
|
int x,y,res;
|
||||||
|
unsigned char * tmpbuffer = (unsigned char *)malloc(width*height*3);
|
||||||
|
memset(tmpbuffer, 0, width*height*3);
|
||||||
|
PNGU_u32 ARGBColor;
|
||||||
|
|
||||||
|
for(y=0; y < height; y++)
|
||||||
|
{
|
||||||
|
for(x=0; x < width; x++)
|
||||||
|
{
|
||||||
|
GX_PeekARGB(x, y, &ARGBColor);
|
||||||
|
|
||||||
|
tmpbuffer[y*640*3+x*3] = (((ARGBColor) >>16) & 0xFF); // R
|
||||||
|
tmpbuffer[y*640*3+x*3+1] = (((ARGBColor) >> 8) & 0xFF); // G
|
||||||
|
tmpbuffer[y*640*3+x*3+2] = ( (ARGBColor) & 0xFF); // B
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
res = PNGU_EncodeFromRGB (ctx, width, height, tmpbuffer, stride);
|
||||||
|
free(tmpbuffer);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int PNGU_EncodeFromYCbYCr (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *buffer, PNGU_u32 stride)
|
int PNGU_EncodeFromYCbYCr (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *buffer, PNGU_u32 stride)
|
||||||
{
|
{
|
||||||
|
|
|
@ -157,6 +157,10 @@ int PNGU_DecodeTo4x4RGBA8 (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *bu
|
||||||
// specify context, image dimensions, destination address and stride in pixels (stride = buffer width - image width).
|
// 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_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);
|
||||||
|
int PNGU_EncodeFromEFB (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, PNGU_u32 stride);
|
||||||
|
|
||||||
// Macro for encoding an image stored into an YCbYCr buffer at given coordinates.
|
// 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) \
|
#define PNGU_ENCODE_TO_COORDS_YCbYCr(ctx,coordX,coordY,imgWidth,imgHeight,bufferWidth,bufferHeight,buffer) \
|
||||||
\
|
\
|
||||||
|
|
Loading…
Reference in a new issue