2 * \brief PNG image element
4 * \author Norman Feske <norman.feske@genode-labs.com>
8 * Copyright (C) 2005-2009
9 * Genode Labs, Feske & Helmuth Systementwicklung GbR
11 * This file is part of the Genode OS framework, which is distributed
12 * under the terms of the GNU General Public License version 2.
17 #include <l4/scout-gfx/png_image>
19 #include <l4/mag-gfx/canvas>
20 #include <l4/mag-gfx/factory>
21 #include <l4/mag-gfx/mem_texture>
23 using namespace Mag_gfx;
24 using namespace Scout_gfx;
38 Png_stream(char *addr) { _addr = addr; }
41 * Read from png stream
43 void read(char *dst, int len)
45 memcpy(dst, _addr, len);
54 static void user_read_data(png_structp png_ptr, png_bytep data, png_size_t len)
56 Png_stream *stream = (Png_stream *)png_get_io_ptr(png_ptr);
58 stream->read((char *)data, len);
64 * Dummy to make libl4png happy
66 extern "C" int l4libpng_fread(void *, int, int, void *)
68 printf("l4libpng_fread called - function not implemented\n");
73 /***********************
74 ** Element interface **
75 ***********************/
77 void Png_image::fill_cache(Mag_gfx::Pixel_info const *c)
82 Png_stream *stream = new Png_stream((char *)_png_data);
84 png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
87 png_set_read_fn(png_ptr, stream, user_read_data);
89 png_infop info_ptr = png_create_info_struct(png_ptr);
91 png_destroy_read_struct(&png_ptr, NULL, NULL);
95 png_read_info(png_ptr, info_ptr);
97 /* get image data chunk */
98 int bit_depth, color_type, interlace_type;
100 png_get_IHDR(png_ptr, info_ptr, &w, &h, &bit_depth, &color_type,
101 &interlace_type, NULL, NULL);
105 // printf("png[%p] : load -> sz=%d,%d\n", this, w, h);
107 if (color_type == PNG_COLOR_TYPE_PALETTE)
108 png_set_palette_to_rgb(png_ptr);
110 if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
111 png_set_expand_gray_1_2_4_to_8(png_ptr);
113 if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
114 png_set_gray_to_rgb(png_ptr);
116 if (!(color_type & PNG_COLOR_MASK_ALPHA))
117 png_set_add_alpha(png_ptr, 255, PNG_FILLER_AFTER);
119 png_set_bgr(png_ptr);
121 if (bit_depth < 8) png_set_packing(png_ptr);
122 if (bit_depth == 16) png_set_strip_16(png_ptr);
124 _texture = c->factory->create_texture(_size, 0, true);
126 /* allocate buffer for decoding a row */
127 static png_byte *row_ptr;
128 static int curr_row_size;
130 int needed_row_size = png_get_rowbytes(png_ptr, info_ptr)*8;
132 if (curr_row_size < needed_row_size)
137 row_ptr = (png_byte *)malloc(needed_row_size);
138 curr_row_size = needed_row_size;
141 Mem::Texture<Rgba32> tt((Rgba32::Pixel *)row_ptr, Area(_size.w(), 1));
144 for (int j = 0; j < _size.h(); j++)
146 png_read_row(png_ptr, row_ptr, NULL);
147 _texture->blit(&tt, j);
153 void Png_image::flush_cache(Mag_gfx::Pixel_info const *)
160 void Png_image::draw(Canvas *c, Point const &p)
163 /* if texture is not ready, try to initialize it */
166 fill_cache(c->type());
173 c->draw_texture(_texture, Rgb32::Black, p, Canvas::Alpha);