Exemplo n.º 1
0
void a_png_readFile(const char* path, Pixel** pixels, int* width, int* height)
{
    File* const f = a_file_open(path, "r");

    png_structp png = NULL;
    png_infop info = NULL;

    if(!f) {
        goto cleanUp;
    }

    #define PNG_SIG 8
    png_byte sig[PNG_SIG];

    a_file_read(f, sig, PNG_SIG);

    if(png_sig_cmp(sig, 0, PNG_SIG) != 0) {
        a_error("%s is not a PNG", path);
        goto cleanUp;
    }

    png = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);

    if(!png) {
        goto cleanUp;
    }

    info = png_create_info_struct(png);

    if(!info) {
        goto cleanUp;
    }

    if(setjmp(png_jmpbuf(png))) {
        goto cleanUp;
    }

    png_init_io(png, a_file_handle(f));
    png_set_sig_bytes(png, PNG_SIG);
    png_read_png(png, info, PNG_TRANSFORM_IDENTITY, NULL);

    const int type = png_get_color_type(png, info);

    if(type != PNG_COLOR_TYPE_RGB && type != PNG_COLOR_TYPE_RGBA) {
        a_error("%s not 8-bit RGBA PNG", path);
        goto cleanUp;
    }

    pngToPixels(png, info, pixels, width, height);

    cleanUp:

    if(png) {
        png_destroy_read_struct(&png, info ? &info : NULL, NULL);
    }

    if(f) {
        a_file_close(f);
    }
}
Exemplo n.º 2
0
void a_png_write(const char* path, const Pixel* data, int width, int height)
{
    File* f = a_file_open(path, "w");

    png_structp png = NULL;
    png_infop info = NULL;
    png_bytepp rows = NULL;

    if(!f) {
        goto cleanUp;
    }

    rows = malloc(height * sizeof(png_bytep));
    memset(rows, 0, height * sizeof(png_bytep));

    png = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);

    if(!png) {
        goto cleanUp;
    }

    info = png_create_info_struct(png);

    if(!info) {
        goto cleanUp;
    }

    if(setjmp(png_jmpbuf(png))) {
        goto cleanUp;
    }

    png_set_compression_level(png, Z_BEST_COMPRESSION);

    png_set_IHDR(
        png, info,
        width, height,
        8, PNG_COLOR_TYPE_RGB,
        PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT,
        PNG_FILTER_TYPE_DEFAULT
    );

    for(int i = 0; i < height; i++) {
        rows[i] = malloc(width * 3 * sizeof(png_byte));

        for(int j = 0; j < width; j++) {
            const Pixel p = *(data + i * width + j);

            rows[i][j * 3 + 0] = a_pixel_red(p);
            rows[i][j * 3 + 1] = a_pixel_green(p);
            rows[i][j * 3 + 2] = a_pixel_blue(p);
        }
    }

    png_init_io(png, a_file_handle(f));
    png_set_rows(png, info, rows);
    png_write_png(png, info, PNG_TRANSFORM_IDENTITY, NULL);
    png_write_end(png, NULL);

    cleanUp:

    if(png) {
        png_destroy_write_struct(&png, info ? &info : NULL);
    }

    if(rows) {
        for(int i = 0; i < height; i++) {
            free(rows[i]);
        }

        free(rows);
    }

    if(f) {
        a_file_close(f);
    }
}
Exemplo n.º 3
0
void a_png_write(const char* Path, const APixel* Data, int Width, int Height, char* Title, char* Description)
{
    AFile* f = a_file_open(Path, "wb");

    png_structp png = NULL;
    png_infop info = NULL;
    png_bytepp rows = NULL;
    png_text text[2];
    int numText = 0;

    if(!f) {
        goto cleanUp;
    }

    rows = a_mem_malloc(Height * sizeof(png_bytep));
    memset(rows, 0, Height * sizeof(png_bytep));

    png = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);

    if(!png) {
        goto cleanUp;
    }

    info = png_create_info_struct(png);

    if(!info) {
        goto cleanUp;
    }

    if(setjmp(png_jmpbuf(png))) {
        goto cleanUp;
    }

    png_set_compression_level(png, Z_BEST_COMPRESSION);

    png_set_IHDR(
        png, info,
        Width, Height,
        8, PNG_COLOR_TYPE_RGB,
        PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT,
        PNG_FILTER_TYPE_DEFAULT
    );

    for(int i = 0; i < Height; i++) {
        rows[i] = a_mem_malloc(Width * 3 * sizeof(png_byte));

        for(int j = 0; j < Width; j++) {
            const APixel p = *(Data + i * Width + j);

            rows[i][j * 3 + 0] = a_pixel_red(p);
            rows[i][j * 3 + 1] = a_pixel_green(p);
            rows[i][j * 3 + 2] = a_pixel_blue(p);
        }
    }

    if(Title != NULL) {
        text[numText].compression = PNG_TEXT_COMPRESSION_NONE;
        text[numText].key = "Title";
        text[numText].text = Title;
        numText++;
    }

    if(Description != NULL) {
        text[numText].compression = PNG_TEXT_COMPRESSION_NONE;
        text[numText].key = "Description";
        text[numText].text = Description;
        numText++;
    }

    png_init_io(png, a_file_handle(f));
    png_set_rows(png, info, rows);
    png_set_text(png, info, text, numText);
    png_write_png(png, info, PNG_TRANSFORM_IDENTITY, NULL);
    png_write_end(png, NULL);

cleanUp:
    if(png) {
        png_destroy_write_struct(&png, info ? &info : NULL);
    }

    if(rows) {
        for(int i = 0; i < Height; i++) {
            free(rows[i]);
        }

        free(rows);
    }

    if(f) {
        a_file_close(f);
    }
}