kakwa / libemf2svg

Microsoft (MS) EMF to SVG conversion library

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

bitmaps with alpha channels show up as black boxes

Cian-Chambliss opened this issue · comments

Tracked this down to the fact that the alpha channel is ignored in emf2svg_img_utils.c

This appears to be purposeful as there is an inconsistency in windows DIBs where if the alpha channel is not used, it is all zeros (instead of all 0xff as one would expect).

I found that If the bitmap is tested for any non-zeros in the alpha channel, it handles both RGB and RGBA bitmaps properly.

int rgb2png(RGBABitmap _bitmap, char *_out, size_t _size) {
FILE *fp = open_memstream(out, size);
if (fp == NULL) {
return -1;
}
png_structp png_ptr = NULL;
png_infop info_ptr = NULL;
size_t x, y;
size_t width_by_height;
// png_uint_32 bytes_per_row;
png_byte *_row_pointers = NULL;
bool alpha_channel_empty = true;

if (fp == NULL)
    return -1;

/* Initialize the write struct. */
png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if (png_ptr == NULL) {
    fclose(fp);
    return -1;
}

/* Initialize the info struct. */
info_ptr = png_create_info_struct(png_ptr);
if (info_ptr == NULL) {
    png_destroy_write_struct(&png_ptr, NULL);
    fclose(fp);
    return -1;
}

/* Set up error handling. */
if (setjmp(png_jmpbuf(png_ptr))) {
    png_destroy_write_struct(&png_ptr, &info_ptr);
    fclose(fp);
    return -1;
}

/* Set image attributes. */
png_set_IHDR(png_ptr, info_ptr, bitmap->width, bitmap->height, 8,
             PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE,
             PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);

/* Initialize rows of PNG. */
// bytes_per_row = bitmap->width * bytes_per_pixel;
row_pointers = png_malloc(png_ptr, bitmap->height * sizeof(png_byte *));
// Check to see if alpha channel is used (nonzero)
width_by_height = bitmap->width * bitmap->height;
for( x = 0 ; x < width_by_height ; ++x ) {
    if( bitmap->pixels[x].alpha ) {
       alpha_channel_empty = false;
       break;
    }
}

for (y = 0; y < bitmap->height; ++y) {
    uint8_t *row = png_malloc(png_ptr, sizeof(uint8_t) * bitmap->width * 4);
    // row_pointers[y] = (png_byte *)row;
    row_pointers[bitmap->height - y - 1] = row;
    if( alpha_channel_empty ) {
        for (x = 0; x < bitmap->width; ++x) {
            // RGBPixel *color = pixel_at(bitmap, x, y);
            RGBAPixel color = bitmap->pixels[((x + bitmap->width * y))];
            // printf("(%d, %d)\n", bitmap->width, bitmap->height);
            // printf("(%d, %d)\n", x, y);
            // printf("color:0x%0X%0X%0x\n", color.red, color.green,
            // color.blue);
            *row++ = color.red;
            *row++ = color.green;
            *row++ = color.blue;
            //*row++ = color.alpha;
            *row++ = 0xFF;
        }
    } else {
        for(x = 0; x < bitmap->width ; ++x ) {
            RGBAPixel color = bitmap->pixels[((x + bitmap->width * y))];
            *row++ = color.red;
            *row++ = color.green;
            *row++ = color.blue;
            *row++ = color.alpha;
        }
    }
}

/* Actually write the image data. */
png_init_io(png_ptr, fp);
png_set_rows(png_ptr, info_ptr, row_pointers);
png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL);

/* Cleanup. */
for (y = 0; y < bitmap->height; y++) {
    png_free(png_ptr, row_pointers[y]);
}
png_free(png_ptr, row_pointers);

/* Finish writing. */
png_destroy_write_struct(&png_ptr, &info_ptr);
fflush(fp);
fclose(fp);
return 0;

}

Hi,

Thank you for your bug report.

Do you have emf files containing DIBs with transparency that I could include in the test suit?

(Just in case, if you have some emf with RLE4 and/or RLE8 compressed DIBs, it would be awesome)

Hello,

I attached the EMF with a signature that I had used for testing.

I have the source changes in a fork of the repo here:

https://github.com/Cian-Chambliss/libemf2svg

I have also been adding change like

  1. support for DIB pattern brushs
  2. support for BitBlt to set a background (NULL source bitmap, use current
    fill color) I have a test case for this one to if you are interested.

Thanks,
Cian Chambliss

On Mon, Apr 4, 2016 at 12:57 PM, Carpentier Pierre-Francois <
notifications@github.com> wrote:

Hi,

Thank you for your bug report.

Do you have emf files containing DIBs with transparency that I could
include in the test suit?

(Just in case, if you have some emf with RLE4 and/or RLE8 compressed DIBs,
it would be awesome)


You are receiving this because you authored the thread.
Reply to this email directly or view it on GitHub
#5 (comment)

Thanks for the patches,

your modifications has been included in version 0.5.0.

Thank you again ^^

Thanks - I probably should have started another issue on this, but I also
ran into another problem when running this under OSX - I found that I had
to add

#ifdef DARWIN
#include <memstream.h>
#endif

To the headers section in

libemf2svg/src/lib/emf2svg_img_utils.c

To avoid getting an exception in libPNG due to a missing prototype (the
open_memstream() was being treated as an int, which was trashing the
pointer to the FILE *.

On Mon, Apr 11, 2016 at 4:06 PM, Carpentier Pierre-Francois <
notifications@github.com> wrote:

Thanks for the patches,

your modifications has been included in version 0.5.0.

Thank you again ^^


You are receiving this because you authored the thread.
Reply to this email directly or view it on GitHub
#5 (comment)

I've open another issue for this:
#6

@Cian-Chambliss I've fixed many issues on OS X compilation in version 0.5.1 + added some CI.

@Cian-Chambliss could you run clang-format and make a pull request?

clang-format -style="{BasedOnStyle: llvm, IndentWidth: 4, AllowShortFunctionsOnASingleLine: None, KeepEmptyLinesAtTheStartOfBlocks: false}" -i \
    `find ./src/ ./inc/ -type f -name "*.cpp" -o \
                        -type f -name "*.c" -o \
                        -type f -name "*.h" -o \
                        -type f -name "*.hpp"`

or the helper script that does the same thing:

./goodies/format

It's not mandatory, but it would be nice if you kept ownership of the lines of code you have contributed to.

This might be unique to OS X environment, but running the clang-format
command changed the include order to be alphabetized - this is a problem
as it broke the build for me, some of the headers included references to
the drawingStates class that is declared in emf2svg_private.h.

Should these headers pull in emf2svg_private.h? multiple inclusion can be
prevented by adding a #define - i.e.

#ifndef _EMF2SVG_PRIVATE_INCL
#define _EMF2SVG_PRIVATE_INCL
...
#endif

I wasn't sure if this made sense, or if it makes more sense to move the
offending prototypes into emf2svg_private.h.

On Wed, Apr 13, 2016 at 5:53 PM, Carpentier Pierre-Francois <
notifications@github.com> wrote:

@Cian-Chambliss https://github.com/Cian-Chambliss could you run
clang-format and make a pull request?

clang-format -style="{BasedOnStyle: llvm, IndentWidth: 4, AllowShortFunctionsOnASingleLine: None, KeepEmptyLinesAtTheStartOfBlocks: false}" -i
find ./src/ ./inc/ -type f -name "*.cpp" -o \ -type f -name "*.c" -o \ -type f -name "*.h" -o \ -type f -name "*.hpp"

or the helper script that does the same thing:

./goodies/format

It's not mandatory, but it would be nice if you kept ownership of the
lines of code you have contributed to.


You are receiving this because you were mentioned.
Reply to this email directly or view it on GitHub
#5 (comment)

I've done the clang-format in commit a2f4e2b

And commited with a little --author trickery

git commit -a --author="cian-chambliss <cian AT alphasoftware.com>"

If you're not okay with that, I can remove this commit.

That fine , I was just curious as to why clang- format was reordering the headers , and why that broke the build on my end.

I will pull the master branch on the original repo and see if it builds. if it does, I will merge the changes into my repo.

My end goal is to get this working under Windows as well for an open source print to svg.

Thanks ,
Cian

Sent from my iPhone

On Apr 14, 2016, at 1:32 AM, Carpentier Pierre-Francois notifications@github.com wrote:

I've done the clang-format in commit a2f4e2b

And commited with a little --author trickery

git commit -a --author="cian-chambliss "
If you're not okay with that, I can remove this commit.


You are receiving this because you were mentioned.
Reply to this email directly or view it on GitHub