[CHG] Modify GRRLIB_ScrShot to work with EFB (maybe...)

This commit is contained in:
Crayon2000 2009-12-01 20:20:16 +00:00
parent 740a81df7e
commit 10aee9c66b
4 changed files with 170 additions and 6 deletions

View file

@ -94,9 +94,9 @@ bool GRRLIB_ScrShot(const char* filename) {
int ret = -1;
if ( (pngContext = PNGU_SelectImageFromDevice(filename)) ) {
ret = PNGU_EncodeFromYCbYCr( pngContext,
ret = PNGU_EncodeFromEFB( pngContext,
rmode->fbWidth, rmode->efbHeight,
xfb[fb], 0 );
0 );
PNGU_ReleaseImageContext(pngContext);
}
return !ret;

View file

@ -682,6 +682,166 @@ int PNGU_DecodeTo4x4RGBA8 (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *bu
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)
{

View file

@ -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).
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.
#define PNGU_ENCODE_TO_COORDS_YCbYCr(ctx,coordX,coordY,imgWidth,imgHeight,bufferWidth,bufferHeight,buffer) \
\