#include <stdlib.h>
#include <string.h>
#include <png.h>
+#include "plat.h"
#include "readpng.h"
#include "lprintf.h"
switch (what)
{
+ case READPNG_SCALE:
+ {
+ int height, width, x_ofs = 0, y_ofs = 0;
+ unsigned short *dst = dest;
+ int x_scale, y_scale, x_pos, y_pos; // Q16
+
+ if (png_get_bit_depth(png_ptr, info_ptr) != 8)
+ {
+ lprintf(__FILE__ ": scaled image uses %ibpc, needed 8bpc\n", png_get_bit_depth(png_ptr, info_ptr));
+ goto done;
+ }
+ width = png_get_image_width(png_ptr, info_ptr);
+ x_scale = width*65536 / req_w;
+ height = png_get_image_height(png_ptr, info_ptr);
+ y_scale = height*65536 / req_h;
+ if (x_scale < y_scale)
+ x_scale = y_scale;
+ else y_scale = x_scale;
+ x_ofs = req_w - width*65536 / x_scale;
+ y_ofs = req_h - height*65536 / y_scale;
+
+ dst += y_ofs/2*req_w + x_ofs/2;
+ for (y_pos = 0; y_pos < height*65536; y_pos += y_scale+1)
+ {
+ unsigned char *src = row_ptr[y_pos >> 16];
+ int len = 0;
+ for (x_pos = 0; x_pos < width*65536; x_pos += x_scale+1, len++)
+ {
+ int o = 3*(x_pos >> 16);
+ // TODO: could use bilinear if upsampling?
+ *dst++ = PXMAKE(src[o], src[o+1], src[o+2]);
+ }
+ dst += req_w - len;
+ }
+ break;
+ }
+
case READPNG_BG:
{
- int height, width, h;
+ int height, width, h, x_ofs = 0, y_ofs = 0;
unsigned short *dst = dest;
+
if (png_get_bit_depth(png_ptr, info_ptr) != 8)
{
lprintf(__FILE__ ": bg image uses %ibpc, needed 8bpc\n", png_get_bit_depth(png_ptr, info_ptr));
- break;
+ goto done;
}
width = png_get_image_width(png_ptr, info_ptr);
- if (width > req_w)
+ if (width > req_w) {
+ x_ofs = (width - req_w) / 2;
width = req_w;
+ } else
+ dst += (req_w - width) / 2;
height = png_get_image_height(png_ptr, info_ptr);
- if (height > req_h)
+ if (height > req_h) {
+ y_ofs = (height - req_h) / 2;
height = req_h;
+ } else
+ dst += (req_h - height) / 2 * req_w;
for (h = 0; h < height; h++)
{
- unsigned char *src = row_ptr[h];
+ unsigned char *src = row_ptr[h + y_ofs] + x_ofs * 3;
int len = width;
while (len--)
{
-#ifdef PSP
- *dst++ = ((src[2]&0xf8)<<8) | ((src[1]&0xf8)<<3) | (src[0] >> 3); // BGR
-#else
- *dst++ = ((src[0]&0xf8)<<8) | ((src[1]&0xf8)<<3) | (src[2] >> 3); // RGB
-#endif
+ *dst++ = PXMAKE(src[0], src[1], src[2]);
src += 3;
}
dst += req_w - width;
{
lprintf(__FILE__ ": unexpected font image size %dx%d, needed %dx%d\n",
(int)png_get_image_width(png_ptr, info_ptr), (int)png_get_image_height(png_ptr, info_ptr), req_w, req_h);
- break;
+ goto done;
}
if (png_get_bit_depth(png_ptr, info_ptr) != 8)
{
lprintf(__FILE__ ": font image uses %ibpp, needed 8bpp\n", png_get_bit_depth(png_ptr, info_ptr));
- break;
+ goto done;
}
for (y = 0; y < 16; y++)
{
{
lprintf(__FILE__ ": unexpected selector image size %ix%i, needed %dx%d\n",
(int)png_get_image_width(png_ptr, info_ptr), (int)png_get_image_height(png_ptr, info_ptr), req_w, req_h);
- break;
+ goto done;
}
if (png_get_bit_depth(png_ptr, info_ptr) != 8)
{
lprintf(__FILE__ ": selector image uses %ibpp, needed 8bpp\n", png_get_bit_depth(png_ptr, info_ptr));
- break;
+ goto done;
}
for (y1 = 0; y1 < req_h; y1++)
{
if (png_get_bit_depth(png_ptr, info_ptr) != 8)
{
lprintf(__FILE__ ": image uses %ibpc, needed 8bpc\n", png_get_bit_depth(png_ptr, info_ptr));
- break;
+ goto done;
}
width = png_get_image_width(png_ptr, info_ptr);
if (width > req_w)
return ret;
}
-int writepng(const char *fname, unsigned short *src, int w, int h)
+int writepngpp(const char *fname, unsigned short *src, int w, int h, int pitch)
{
png_structp png_ptr = NULL;
png_infop info_ptr = NULL;
goto end2;
row_pointers[i] = dst;
for (j = 0; j < w; j++, src++, dst += 3) {
- dst[0] = (*src & 0xf800) >> 8;
- dst[1] = (*src & 0x07e0) >> 3;
- dst[2] = (*src & 0x001f) << 3;
+ dst[0] = PXGETR(*src);
+ dst[1] = PXGETG(*src);
+ dst[2] = PXGETB(*src);
}
+ src += pitch-w;
}
/* initialize stuff */
return ret;
}
+int writepng(const char *fname, unsigned short *src, int w, int h)
+{
+ return writepngpp(fname, src, w, h, w);
+}