randy408 / libspng

Simple, modern libpng alternative
https://libspng.org
BSD 2-Clause "Simplified" License
736 stars 74 forks source link

No subimage when creating an image from scratch #261

Open alevesely opened 1 year ago

alevesely commented 1 year ago

I'm unable to create an image from computed values.

For example (skipping error checks):

    spng_ctx *ctx = spng_ctx_new(SPNG_CTX_ENCODER);
    FILE *fp = fopen("my.png", "w");
    spng_set_png_file(ctx, fp);

    struct spng_ihdr ihdr = {0}; /* zero-initialize to set valid defaults */
    ihdr.width = 400;
    ihdr.height = 256;
    ihdr.color_type = SPNG_COLOR_TYPE_TRUECOLOR;
    ihdr.bit_depth = 8;
    spng_set_ihdr(ctx, &ihdr); // this does not calculate subimage

    size_t size = 4*400;
    unsigned char *linebuf = malloc(size);
    for (int i = 0; i < 256; ++i)
    {
                calculate_line_colors(linebuf);
        ret = spng_encode_scanline(ctx, linebuf, size);

        if(ret)
        {
            printf("spng_encode_scanline() error: %s\n", spng_strerror(ret));
            goto encode_error;
        }
    }

This prints "spng_encode_scanline() error: invalid buffer size" at line 4689 in spng.c as it checks len < (ctx->subimage[ctx->row_info.pass].scanline_width -1); scanline_width is 0, and subtracting 1 overflows.

If instead I call spng_encode_row() it prints "internal error", from line 4574 in spng.c, after it finds scanline_width to be 0.

randy408 commented 1 year ago

For progressive image encoding you have to initialize with spng_encode_image(ctx, NULL, 0, SPNG_FMT_PNG, SPNG_ENCODE_PROGRESSIVE); as described in the Progressive image encoding section.

I should probably do some extra error checking for this and return SPNG_EOPSTATE ("invalid operation for state") or something.