Acked-by: Christophe Fergeau <cfergeau@xxxxxxxxxx> On Tue, Jul 25, 2017 at 06:33:34PM +0100, Frediano Ziglio wrote: > -uint8_t *PngCoder::from_bitmap(const BITMAPINFO& info, const void *bits, long &size) > +uint8_t *PngCoder::from_bitmap(const BITMAPINFO& bmp_info, const void *bits, long &size) Just a small general comment, in my opinion, long functions (more than say 50 lines) doing multiple unrelated things are usually better split in several smaller functions. Christophe > { > - // TODO not implemented > - return NULL; > + // this vector is here to avoid leaking resources if libpng use setjmp/longjmp > + std::vector<png_color> palette; > + WriteBufferIo io; > + > + png_structp png = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); > + if (!png) > + return 0; > + > + png_infop info = png_create_info_struct(png); > + if (!info) { > + png_destroy_write_struct(&png, &info); > + return 0; > + } > + > + if (setjmp(png_jmpbuf(png))) { > + png_destroy_write_struct(&png, &info); > + return 0; > + } > + > + png_set_write_fn(png, &io, write_to_bufio, flush_bufio); > + > + const BITMAPINFOHEADER& head(bmp_info.bmiHeader); > + int color_type; > + int out_bits = head.biBitCount; > + switch (out_bits) { > + case 1: > + case 4: > + case 8: > + color_type = PNG_COLOR_TYPE_PALETTE; > + break; > + case 24: > + case 32: > + png_set_bgr(png); > + color_type = PNG_COLOR_TYPE_RGB; > + break; > + default: > + png_error(png, "BMP bit count not supported"); > + break; > + } > + // TODO detect gray > + png_set_IHDR(png, info, head.biWidth, head.biHeight, > + out_bits > 8 ? 8 : out_bits, color_type, > + PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, > + PNG_FILTER_TYPE_DEFAULT); > + > + // palette > + if (color_type == PNG_COLOR_TYPE_PALETTE) { > + palette.resize(head.biClrUsed); > + const RGBQUAD *rgb = bmp_info.bmiColors; > + for (unsigned int color = 0; color < head.biClrUsed; ++color) { > + palette[color].red = rgb->rgbRed; > + palette[color].green = rgb->rgbGreen; > + palette[color].blue = rgb->rgbBlue; > + ++rgb; > + } > + png_set_PLTE(png, info, &palette[0], palette.size()); > + } > + > + png_write_info(png, info); > + > + const unsigned int width = head.biWidth; > + const unsigned int height = head.biHeight; > + const size_t stride = compute_dib_stride(width, out_bits); > + const size_t image_size = stride * height; > + > + // now do the actual conversion! > + const uint8_t *src = (const uint8_t*)bits + image_size; > + for (unsigned int row = 0; row < height; ++row) { > + src -= stride; > + png_write_row(png, src); > + } > + png_write_end(png, NULL); > + > + png_destroy_write_struct(&png, &info); > + size = io.pos; > + return io.release(); > } > > ImageCoder *create_png_coder() > -- > 2.13.3 > > _______________________________________________ > Spice-devel mailing list > Spice-devel@xxxxxxxxxxxxxxxxxxxxx > https://lists.freedesktop.org/mailman/listinfo/spice-devel
Attachment:
signature.asc
Description: PGP signature
_______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/spice-devel