/* Transcribe one scanline from the GIF to the picogui bitmap */ void dither_transcribe_line(hwrdither d, GifFileType *f, int transparent_flag, int transparent_color) { pgcolor c; u8 pixel; GifColorType *color; int x; for (x=0;x<f->Image.Width;x++) { DGifGetPixel(f, &pixel); color = f->SColorMap->Colors + (pixel % f->SColorMap->ColorCount); if (transparent_flag) { c = mkcolora(pixel==transparent_color ? 0 : 127,color->Red,color->Green,color->Blue); } else { c = mkcolor(color->Red,color->Green,color->Blue); } vid->dither_store(d,c,PG_LGOP_NONE); } }
/* Transcribe one scanline from the GIF to the picogui bitmap */ void transcribe_line(hwrbitmap b, GifFileType *f, int y, int transparent_flag, int transparent_color) { pgcolor c; u8 pixel; GifColorType *color; int x; for (x=0;x<f->Image.Width;x++) { DGifGetPixel(f, &pixel); color = f->SColorMap->Colors + (pixel % f->SColorMap->ColorCount); if (transparent_flag) { c = mkcolora(pixel==transparent_color ? 0 : 127,color->Red,color->Green,color->Blue); } else { c = mkcolor(color->Red,color->Green,color->Blue); } vid->pixel(b,x,y,VID(color_pgtohwr)(c),PG_LGOP_NONE); } }
g_error png_load(hwrbitmap *hbmp, const u8 *data, u32 datalen) { png_structp png_ptr; png_infop info_ptr; struct datablock d; png_bytep *row_pointers; png_uint_32 width, height; int bit_depth,colortype,interlace; int x,y; u8 r,g,b,a; pgcolor c; png_bytep p; g_error e; png_colorp palette; int num_palette; png_colorp pp; png_bytep trans; int num_trans = 0; #ifdef CONFIG_DITHER hwrdither dither; #endif png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (!png_ptr) return mkerror(PG_ERRT_IO, 68); /* Error initializing libpng */ info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) { png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL); return mkerror(PG_ERRT_IO, 68); /* Error initializing libpng */ } /* Set libpng error handler */ if (setjmp(png_jmpbuf(png_ptr))) { png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); return mkerror(PG_ERRT_IO, 71); /* Error reading PNG */ } /* Set libpng read handler */ d.data = data; d.length = datalen; png_set_read_fn(png_ptr, &d, (png_rw_ptr) &png_user_read_data); /* Read the png into memory */ png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_STRIP_16 | PNG_TRANSFORM_PACKING, NULL); row_pointers = png_get_rows(png_ptr, info_ptr); png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &colortype, &interlace, NULL, NULL); if (colortype == PNG_COLOR_TYPE_PALETTE) { png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette); png_get_tRNS(png_ptr, info_ptr, &trans, &num_trans, NULL); } if (interlace != PNG_INTERLACE_NONE) fprintf(stderr, "png loader: OOPS... interlaced image, will b0rk\n"); /* Allocate the picogui bitmap * * Important note: normally we create bitmaps at the display's * color depth, but if we have an alpha channel * we need room for ARGB colors. */ if (colortype == PNG_COLOR_TYPE_GRAY_ALPHA || colortype == PNG_COLOR_TYPE_RGB_ALPHA || num_trans) e = vid->bitmap_new(hbmp,width,height,32); else e = vid->bitmap_new(hbmp,width,height,vid->bpp); if (iserror(e)) png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); errorcheck; #ifdef CONFIG_DITHER /* Start dithering */ e = vid->dither_start(&dither, *hbmp, 0,0,0,width,height); errorcheck; #endif /* Transcribe it into a picogui bitmap. * This method is slow, but ensures compatibility */ for (y=0;y<height;y++) { p = row_pointers[y]; for (x=0;x<width;x++) { switch (colortype) { case PNG_COLOR_TYPE_GRAY: g = *(p++); c = mkcolor(g,g,g); break; case PNG_COLOR_TYPE_GRAY_ALPHA: g = *(p++); a = *(p++); c = mkcolora(a>>1,g,g,g); break; case PNG_COLOR_TYPE_PALETTE: pp = &palette[ (*p) % num_palette ]; if (*p < num_trans) c = mkcolora(trans[*p]>>1, pp->red, pp->green, pp->blue); else if (num_trans) c = mkcolora(0x7f, pp->red, pp->green, pp->blue); else c = mkcolor(pp->red, pp->green, pp->blue); p++; break; case PNG_COLOR_TYPE_RGB: r = *(p++); g = *(p++); b = *(p++); c = mkcolor(r,g,b); break; case PNG_COLOR_TYPE_RGB_ALPHA: r = *(p++); g = *(p++); b = *(p++); a = *(p++); c = mkcolora(a>>1,r,g,b); break; } #ifdef CONFIG_DITHER vid->dither_store(dither, c, PG_LGOP_NONE); #else vid->pixel(*hbmp,x,y,VID(color_pgtohwr)(c),PG_LGOP_NONE); #endif } }