[Spice-devel] [vdagent-win PATCH v13 4/6] Support encoding PNG images

Christophe Fergeau cfergeau at redhat.com
Wed Jul 26 09:40:11 UTC 2017


Acked-by: Christophe Fergeau <cfergeau at redhat.com>

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 at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/spice-devel
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 801 bytes
Desc: not available
URL: <https://lists.freedesktop.org/archives/spice-devel/attachments/20170726/7698056c/attachment.sig>


More information about the Spice-devel mailing list