src/lib/png.c
author Tero Marttila <terom@qmsk.net>
Mon, 03 Jul 2017 23:15:14 +0300
changeset 177 b2768f3982f3
parent 127 df89d13f2354
permissions -rw-r--r--
src/lib: include string.h
56
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     1
#include "png.h" // pt_png header
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     2
#include "error.h"
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     3
#include "shared/log.h" // debug only
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     4
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     5
#include <png.h> // sysmtem libpng header
177
b2768f3982f3 src/lib: include string.h
Tero Marttila <terom@qmsk.net>
parents: 127
diff changeset
     6
#include <string.h>
56
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     7
#include <assert.h>
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     8
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     9
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    10
#define min(a, b) (((a) < (b)) ? (a) : (b))
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    11
69
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
    12
int pt_png_check (const char *path)
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
    13
{
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
    14
    FILE *fp;
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
    15
    uint8_t header[8];
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
    16
    int ret;
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
    17
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
    18
    // fopen
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
    19
    if ((fp = fopen(path, "rb")) == NULL)
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
    20
        RETURN_ERROR(PT_ERR_IMG_OPEN);
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
    21
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
    22
    // read
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
    23
    if (fread(header, 1, sizeof(header), fp) != sizeof(header))
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
    24
        JUMP_SET_ERROR(ret, PT_ERR_IMG_FORMAT);
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
    25
      
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
    26
    // compare signature  
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
    27
    if (png_sig_cmp(header, 0, sizeof(header)))
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
    28
        // not a PNG file
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
    29
        ret = 1;
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
    30
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
    31
    else
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
    32
        // valid PNG file
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
    33
        ret = 0;
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
    34
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
    35
error:
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
    36
    // cleanup
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
    37
    fclose(fp);
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
    38
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
    39
    return ret;
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
    40
}
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
    41
56
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    42
int pt_png_open (struct pt_image *image, struct pt_png_img *img)
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    43
{
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    44
    int err;
69
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
    45
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
    46
    // init
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
    47
    memset(img, 0, sizeof(*img));
56
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    48
    
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    49
    // open I/O
69
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
    50
    if ((err = pt_image_open_file(image, &img->fh)))
56
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    51
        JUMP_ERROR(err);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    52
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    53
    // create the struct
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    54
    if ((img->png = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL)) == NULL)
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    55
        JUMP_SET_ERROR(err, PT_ERR_PNG_CREATE);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    56
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    57
    // create the info
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    58
    if ((img->info = png_create_info_struct(img->png)) == NULL)
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    59
        JUMP_SET_ERROR(err, PT_ERR_PNG_CREATE);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    60
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    61
    // setup error trap for the I/O
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    62
    if (setjmp(png_jmpbuf(img->png)))
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    63
        JUMP_SET_ERROR(err, PT_ERR_PNG);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    64
    
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    65
    // setup error trap
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    66
    if (setjmp(png_jmpbuf(img->png)))
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    67
        JUMP_SET_ERROR(err, PT_ERR_PNG);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    68
    
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    69
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    70
    // setup I/O to FILE
69
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
    71
    png_init_io(img->png, img->fh);
56
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    72
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    73
    // read meta-info
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    74
    png_read_info(img->png, img->info);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    75
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    76
69
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
    77
    // img->fh will be closed by pt_png_release_read
56
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    78
    return 0;
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    79
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    80
error:
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    81
    // cleanup
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    82
    pt_png_release_read(img);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    83
    
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    84
    return err;
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    85
}
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    86
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    87
int pt_png_read_header (struct pt_png_img *img, struct pt_png_header *header, size_t *data_size)
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    88
{
69
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
    89
    // check image doesn't use any options we don't handle
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
    90
    if (png_get_interlace_type(img->png, img->info) != PNG_INTERLACE_NONE) {
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
    91
        log_warn("Can't handle interlaced PNG");
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
    92
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
    93
        RETURN_ERROR(PT_ERR_IMG_FORMAT);
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
    94
    }
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
    95
56
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    96
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    97
    // initialize
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    98
    memset(header, 0, sizeof(*header));
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    99
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   100
    // fill in basic info
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   101
    header->width = png_get_image_width(img->png, img->info);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   102
    header->height = png_get_image_height(img->png, img->info);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   103
    header->bit_depth = png_get_bit_depth(img->png, img->info);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   104
    header->color_type = png_get_color_type(img->png, img->info);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   105
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   106
    log_debug("width=%u, height=%u, bit_depth=%u, color_type=%u", 
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   107
            header->width, header->height, header->bit_depth, header->color_type
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   108
    );
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   109
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   110
    // only pack 1 pixel per byte, changes rowbytes
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   111
    if (header->bit_depth < 8)
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   112
        png_set_packing(img->png);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   113
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   114
    // fill in other info
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   115
    header->row_bytes = png_get_rowbytes(img->png, img->info);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   116
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   117
    // calculate bpp as num_channels * bpc
69
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
   118
    // this assumes the packed bit depth will be either 8 or 16
56
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   119
    header->col_bytes = png_get_channels(img->png, img->info) * (header->bit_depth == 16 ? 2 : 1);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   120
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   121
    log_debug("row_bytes=%u, col_bytes=%u", header->row_bytes, header->col_bytes);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   122
    
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   123
    // palette etc.
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   124
    if (header->color_type == PNG_COLOR_TYPE_PALETTE) {
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   125
        int num_palette;
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   126
        png_colorp palette;
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   127
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   128
        if (png_get_PLTE(img->png, img->info, &palette, &num_palette) == 0)
69
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
   129
            // PLTE chunk not read?
56
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   130
            RETURN_ERROR(PT_ERR_PNG);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   131
        
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   132
        // should only be 256 of them at most
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   133
        assert(num_palette <= PNG_MAX_PALETTE_LENGTH);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   134
    
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   135
        // copy
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   136
        header->num_palette = num_palette;
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   137
        memcpy(&header->palette, palette, num_palette * sizeof(*palette));
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   138
        
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   139
        log_debug("num_palette=%u", num_palette);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   140
    }
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   141
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   142
    // calculate data size
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   143
    *data_size = header->height * header->row_bytes;
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   144
    
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   145
    return 0;
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   146
}
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   147
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   148
/**
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   149
 * Decode the PNG data directly to memory - not good for sparse backgrounds
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   150
 */
61
31650ef395d3 use pt_png_decode_direct if no background color is set..
Tero Marttila <terom@fixme.fi>
parents: 56
diff changeset
   151
static int pt_png_decode_direct (struct pt_png_img *img, const struct pt_png_header *header, const struct pt_image_params *params, uint8_t *out)
56
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   152
{
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   153
    // write out raw image data a row at a time
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   154
    for (size_t row = 0; row < header->height; row++) {
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   155
        // read row data, non-interlaced
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   156
        png_read_row(img->png, out + row * header->row_bytes, NULL);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   157
    }
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   158
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   159
    return 0;
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   160
}
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   161
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   162
/**
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   163
 * Decode the PNG data, filtering it for sparse regions
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   164
 */
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   165
static int pt_png_decode_sparse (struct pt_png_img *img, const struct pt_png_header *header, const struct pt_image_params *params, uint8_t *out)
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   166
{
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   167
    // one row of pixel data
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   168
    uint8_t *row_buf;
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   169
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   170
    // alloc
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   171
    if ((row_buf = malloc(header->row_bytes)) == NULL)
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   172
        RETURN_ERROR(PT_ERR_MEM);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   173
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   174
    // decode each row at a time
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   175
    for (size_t row = 0; row < header->height; row++) {
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   176
        // read row data, non-interlaced
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   177
        png_read_row(img->png, row_buf, NULL);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   178
        
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   179
        // skip background-colored regions to keep the cache file sparse
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   180
        // ...in blocks of PT_CACHE_BLOCK_SIZE bytes
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   181
        for (size_t col_base = 0; col_base < header->width; col_base += PT_IMG_BLOCK_SIZE) {
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   182
            // size of this block in bytes
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   183
            size_t block_size = min(PT_IMG_BLOCK_SIZE * header->col_bytes, header->row_bytes - col_base);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   184
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   185
            // ...each pixel
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   186
            for (
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   187
                    size_t col = col_base;
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   188
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   189
                    // BLOCK_SIZE * col_bytes wide, don't go over the edge
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   190
                    col < col_base + block_size; 
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   191
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   192
                    col += header->col_bytes
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   193
            ) {
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   194
                // test this pixel
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   195
                if (bcmp(row_buf + col, params->background_color, header->col_bytes)) {
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   196
                    // differs
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   197
                    memcpy(
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   198
                            out + row * header->row_bytes + col_base, 
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   199
                            row_buf + col_base,
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   200
                            block_size
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   201
                    );
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   202
                    
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   203
                    // skip to next block
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   204
                    break;
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   205
                }
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   206
            }
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   207
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   208
            // skip this block
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   209
            continue;
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   210
        }
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   211
    }
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   212
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   213
    return 0;
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   214
}
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   215
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   216
int pt_png_decode (struct pt_png_img *img, const struct pt_png_header *header, const struct pt_image_params *params, uint8_t *out)
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   217
{
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   218
    int err;
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   219
61
31650ef395d3 use pt_png_decode_direct if no background color is set..
Tero Marttila <terom@fixme.fi>
parents: 56
diff changeset
   220
    // decode
108
b81d2fcfa446 handle the png_color as a pointer in png_pixel_data
Tero Marttila <terom@fixme.fi>
parents: 100
diff changeset
   221
    // XXX: it's an array, you silly
61
31650ef395d3 use pt_png_decode_direct if no background color is set..
Tero Marttila <terom@fixme.fi>
parents: 56
diff changeset
   222
    if (params->background_color)
31650ef395d3 use pt_png_decode_direct if no background color is set..
Tero Marttila <terom@fixme.fi>
parents: 56
diff changeset
   223
        err = pt_png_decode_sparse(img, header, params, out);
31650ef395d3 use pt_png_decode_direct if no background color is set..
Tero Marttila <terom@fixme.fi>
parents: 56
diff changeset
   224
31650ef395d3 use pt_png_decode_direct if no background color is set..
Tero Marttila <terom@fixme.fi>
parents: 56
diff changeset
   225
    else
31650ef395d3 use pt_png_decode_direct if no background color is set..
Tero Marttila <terom@fixme.fi>
parents: 56
diff changeset
   226
        err = pt_png_decode_direct(img, header, params, out);
31650ef395d3 use pt_png_decode_direct if no background color is set..
Tero Marttila <terom@fixme.fi>
parents: 56
diff changeset
   227
    
31650ef395d3 use pt_png_decode_direct if no background color is set..
Tero Marttila <terom@fixme.fi>
parents: 56
diff changeset
   228
    if (err)
56
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   229
        return err;
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   230
    
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   231
    // finish off, ignore trailing data
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   232
    png_read_end(img->png, NULL);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   233
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   234
    return 0;
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   235
}
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   236
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   237
int pt_png_info (struct pt_png_header *header, struct pt_image_info *info)
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   238
{
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   239
    // fill in info from header
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   240
    info->img_width = header->width;
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   241
    info->img_height = header->height;
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   242
    info->img_bpp = header->bit_depth;
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   243
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   244
    return 0;
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   245
}
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   246
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   247
/** 
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   248
 * libpng I/O callback: write out data
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   249
 */
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   250
static void pt_png_mem_write (png_structp png, png_bytep data, png_size_t length)
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   251
{
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   252
    struct pt_tile_mem *buf = png_get_io_ptr(png);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   253
    int err;
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   254
    
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   255
    // write to buffer
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   256
    if ((err = pt_tile_mem_write(buf, data, length)))
69
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
   257
        // drop err, because png_error doesn't do formatted output
56
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   258
        png_error(png, "pt_tile_mem_write: ...");
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   259
}
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   260
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   261
/** 
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   262
 * libpng I/O callback: flush buffered data
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   263
 */
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   264
static void pt_png_mem_flush (png_structp png_ptr)
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   265
{
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   266
    // no-op
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   267
}
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   268
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   269
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   270
/**
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   271
 * Return a pointer to the pixel data on \a row, starting at \a col.
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   272
 */
70
35515b3a82b7 more constness for pt_png
Tero Marttila <terom@fixme.fi>
parents: 69
diff changeset
   273
static inline const void* tile_row_col (const struct pt_png_header *header, const uint8_t *data, size_t row, size_t col)
56
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   274
{
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   275
    return data + (row * header->row_bytes) + (col * header->col_bytes);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   276
}
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   277
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   278
/**
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   279
 * Write raw tile image data, directly from the cache
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   280
 */
70
35515b3a82b7 more constness for pt_png
Tero Marttila <terom@fixme.fi>
parents: 69
diff changeset
   281
static int pt_png_encode_direct (struct pt_png_img *img, const struct pt_png_header *header, const uint8_t *data, const struct pt_tile_info *ti)
56
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   282
{
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   283
    for (size_t row = ti->y; row < ti->y + ti->height; row++)
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   284
        // write data directly
70
35515b3a82b7 more constness for pt_png
Tero Marttila <terom@fixme.fi>
parents: 69
diff changeset
   285
        // missing const...
35515b3a82b7 more constness for pt_png
Tero Marttila <terom@fixme.fi>
parents: 69
diff changeset
   286
        png_write_row(img->png, (const png_bytep) tile_row_col(header, data, row, ti->x));
56
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   287
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   288
    return 0;
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   289
}
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   290
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   291
/**
100
aee9d0b12fe9 void png_pixel_data, slight restructuring
Tero Marttila <terom@fixme.fi>
parents: 97
diff changeset
   292
 * Fill in a clipped region of \a width_px pixels at the given row segment
aee9d0b12fe9 void png_pixel_data, slight restructuring
Tero Marttila <terom@fixme.fi>
parents: 97
diff changeset
   293
 */
aee9d0b12fe9 void png_pixel_data, slight restructuring
Tero Marttila <terom@fixme.fi>
parents: 97
diff changeset
   294
static inline void tile_row_fill_clip (const struct pt_png_header *header, png_byte *row, size_t width_px)
aee9d0b12fe9 void png_pixel_data, slight restructuring
Tero Marttila <terom@fixme.fi>
parents: 97
diff changeset
   295
{
aee9d0b12fe9 void png_pixel_data, slight restructuring
Tero Marttila <terom@fixme.fi>
parents: 97
diff changeset
   296
    // XXX: use a configureable background color, or full transparency?
aee9d0b12fe9 void png_pixel_data, slight restructuring
Tero Marttila <terom@fixme.fi>
parents: 97
diff changeset
   297
    memset(row, /* 0xd7 */ 0x00, width_px * header->col_bytes);
aee9d0b12fe9 void png_pixel_data, slight restructuring
Tero Marttila <terom@fixme.fi>
parents: 97
diff changeset
   298
}
aee9d0b12fe9 void png_pixel_data, slight restructuring
Tero Marttila <terom@fixme.fi>
parents: 97
diff changeset
   299
aee9d0b12fe9 void png_pixel_data, slight restructuring
Tero Marttila <terom@fixme.fi>
parents: 97
diff changeset
   300
/**
56
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   301
 * Write clipped tile image data (a tile that goes over the edge of the actual image) by aligning the data from the cache as needed
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   302
 */
70
35515b3a82b7 more constness for pt_png
Tero Marttila <terom@fixme.fi>
parents: 69
diff changeset
   303
static int pt_png_encode_clipped (struct pt_png_img *img, const struct pt_png_header *header, const uint8_t *data, const struct pt_tile_info *ti)
56
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   304
{
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   305
    png_byte *rowbuf;
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   306
    size_t row;
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   307
    
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   308
    // image data goes from (ti->x ... clip_x, ti->y ... clip_y), remaining region is filled
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   309
    size_t clip_x, clip_y;
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   310
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   311
69
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
   312
    // fit the left/bottom edge against the image dimensions
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
   313
    clip_x = min(ti->x + ti->width, header->width);
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
   314
    clip_y = min(ti->y + ti->height, header->height);
56
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   315
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   316
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   317
    // allocate buffer for a single row of image data
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   318
    if ((rowbuf = malloc(ti->width * header->col_bytes)) == NULL)
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   319
        RETURN_ERROR(PT_ERR_MEM);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   320
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   321
    // how much data we actually have for each row, in px and bytes
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   322
    // from [(tile x)---](clip x)
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   323
    size_t row_px = clip_x - ti->x;
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   324
    size_t row_bytes = row_px * header->col_bytes;
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   325
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   326
    // write the rows that we have
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   327
    // from [(tile y]---](clip y)
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   328
    for (row = ti->y; row < clip_y; row++) {
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   329
        // copy in the actual tile data...
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   330
        memcpy(rowbuf, tile_row_col(header, data, row, ti->x), row_bytes);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   331
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   332
        // generate the data for the remaining, clipped, columns
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   333
        tile_row_fill_clip(header, rowbuf + row_bytes, (ti->width - row_px));
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   334
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   335
        // write
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   336
        png_write_row(img->png, rowbuf);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   337
    }
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   338
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   339
    // generate the data for the remaining, clipped, rows
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   340
    tile_row_fill_clip(header, rowbuf, ti->width);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   341
    
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   342
    // write out the remaining rows as clipped data
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   343
    for (; row < ti->y + ti->height; row++)
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   344
        png_write_row(img->png, rowbuf);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   345
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   346
    // ok
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   347
    return 0;
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   348
}
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   349
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   350
/**
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   351
 * Write unscaled tile data
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   352
 */
70
35515b3a82b7 more constness for pt_png
Tero Marttila <terom@fixme.fi>
parents: 69
diff changeset
   353
static int pt_png_encode_unzoomed (struct pt_png_img *img, const struct pt_png_header *header, const uint8_t *data, const struct pt_tile_info *ti)
56
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   354
{
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   355
    int err;
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   356
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   357
    // set basic info
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   358
    png_set_IHDR(img->png, img->info, ti->width, ti->height, header->bit_depth, header->color_type,
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   359
            PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   360
    );
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   361
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   362
    // set palette?
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   363
    if (header->color_type == PNG_COLOR_TYPE_PALETTE)
61
31650ef395d3 use pt_png_decode_direct if no background color is set..
Tero Marttila <terom@fixme.fi>
parents: 56
diff changeset
   364
        // oops... missing const
31650ef395d3 use pt_png_decode_direct if no background color is set..
Tero Marttila <terom@fixme.fi>
parents: 56
diff changeset
   365
        png_set_PLTE(img->png, img->info, (png_colorp) header->palette, header->num_palette);
56
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   366
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   367
    // write meta-info
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   368
    png_write_info(img->png, img->info);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   369
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   370
    // our pixel data is packed into 1 pixel per byte (8bpp or 16bpp)
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   371
    png_set_packing(img->png);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   372
    
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   373
    // figure out if the tile clips
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   374
    if (ti->x + ti->width <= header->width && ti->y + ti->height <= header->height)
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   375
        // doesn't clip, just use the raw data
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   376
        err = pt_png_encode_direct(img, header, data, ti);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   377
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   378
    else
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   379
        // fill in clipped regions
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   380
        err = pt_png_encode_clipped(img, header, data, ti);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   381
    
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   382
    return err;
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   383
}
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   384
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   385
/**
100
aee9d0b12fe9 void png_pixel_data, slight restructuring
Tero Marttila <terom@fixme.fi>
parents: 97
diff changeset
   386
 * Manipulate powers of two
aee9d0b12fe9 void png_pixel_data, slight restructuring
Tero Marttila <terom@fixme.fi>
parents: 97
diff changeset
   387
 */
aee9d0b12fe9 void png_pixel_data, slight restructuring
Tero Marttila <terom@fixme.fi>
parents: 97
diff changeset
   388
static inline size_t scale_by_zoom_factor (size_t value, int z)
aee9d0b12fe9 void png_pixel_data, slight restructuring
Tero Marttila <terom@fixme.fi>
parents: 97
diff changeset
   389
{
aee9d0b12fe9 void png_pixel_data, slight restructuring
Tero Marttila <terom@fixme.fi>
parents: 97
diff changeset
   390
    if (z > 0)
aee9d0b12fe9 void png_pixel_data, slight restructuring
Tero Marttila <terom@fixme.fi>
parents: 97
diff changeset
   391
        return value << z;
aee9d0b12fe9 void png_pixel_data, slight restructuring
Tero Marttila <terom@fixme.fi>
parents: 97
diff changeset
   392
aee9d0b12fe9 void png_pixel_data, slight restructuring
Tero Marttila <terom@fixme.fi>
parents: 97
diff changeset
   393
    else if (z < 0)
aee9d0b12fe9 void png_pixel_data, slight restructuring
Tero Marttila <terom@fixme.fi>
parents: 97
diff changeset
   394
        return value >> -z;
aee9d0b12fe9 void png_pixel_data, slight restructuring
Tero Marttila <terom@fixme.fi>
parents: 97
diff changeset
   395
aee9d0b12fe9 void png_pixel_data, slight restructuring
Tero Marttila <terom@fixme.fi>
parents: 97
diff changeset
   396
    else
aee9d0b12fe9 void png_pixel_data, slight restructuring
Tero Marttila <terom@fixme.fi>
parents: 97
diff changeset
   397
        return value;
aee9d0b12fe9 void png_pixel_data, slight restructuring
Tero Marttila <terom@fixme.fi>
parents: 97
diff changeset
   398
}
aee9d0b12fe9 void png_pixel_data, slight restructuring
Tero Marttila <terom@fixme.fi>
parents: 97
diff changeset
   399
aee9d0b12fe9 void png_pixel_data, slight restructuring
Tero Marttila <terom@fixme.fi>
parents: 97
diff changeset
   400
#define ADD_AVG(l, r) (l) = ((l) + (r)) / 2
aee9d0b12fe9 void png_pixel_data, slight restructuring
Tero Marttila <terom@fixme.fi>
parents: 97
diff changeset
   401
aee9d0b12fe9 void png_pixel_data, slight restructuring
Tero Marttila <terom@fixme.fi>
parents: 97
diff changeset
   402
/**
aee9d0b12fe9 void png_pixel_data, slight restructuring
Tero Marttila <terom@fixme.fi>
parents: 97
diff changeset
   403
 * Converts a pixel's data into a png_color
aee9d0b12fe9 void png_pixel_data, slight restructuring
Tero Marttila <terom@fixme.fi>
parents: 97
diff changeset
   404
 */
108
b81d2fcfa446 handle the png_color as a pointer in png_pixel_data
Tero Marttila <terom@fixme.fi>
parents: 100
diff changeset
   405
static inline void png_pixel_data (const png_color **outp, const struct pt_png_header *header, const uint8_t *data, size_t row, size_t col)
100
aee9d0b12fe9 void png_pixel_data, slight restructuring
Tero Marttila <terom@fixme.fi>
parents: 97
diff changeset
   406
{
111
a31ffb59bc19 reformat png_pixel_data to a switch-case
Tero Marttila <terom@fixme.fi>
parents: 110
diff changeset
   407
    // palette entry number
a31ffb59bc19 reformat png_pixel_data to a switch-case
Tero Marttila <terom@fixme.fi>
parents: 110
diff changeset
   408
    int p;
100
aee9d0b12fe9 void png_pixel_data, slight restructuring
Tero Marttila <terom@fixme.fi>
parents: 97
diff changeset
   409
111
a31ffb59bc19 reformat png_pixel_data to a switch-case
Tero Marttila <terom@fixme.fi>
parents: 110
diff changeset
   410
    switch (header->color_type) {
a31ffb59bc19 reformat png_pixel_data to a switch-case
Tero Marttila <terom@fixme.fi>
parents: 110
diff changeset
   411
        case PNG_COLOR_TYPE_PALETTE:
a31ffb59bc19 reformat png_pixel_data to a switch-case
Tero Marttila <terom@fixme.fi>
parents: 110
diff changeset
   412
            switch (header->bit_depth) {
a31ffb59bc19 reformat png_pixel_data to a switch-case
Tero Marttila <terom@fixme.fi>
parents: 110
diff changeset
   413
                case 8:
a31ffb59bc19 reformat png_pixel_data to a switch-case
Tero Marttila <terom@fixme.fi>
parents: 110
diff changeset
   414
                    // 8bpp palette
a31ffb59bc19 reformat png_pixel_data to a switch-case
Tero Marttila <terom@fixme.fi>
parents: 110
diff changeset
   415
                    p = *((uint8_t *) tile_row_col(header, data, row, col));
a31ffb59bc19 reformat png_pixel_data to a switch-case
Tero Marttila <terom@fixme.fi>
parents: 110
diff changeset
   416
a31ffb59bc19 reformat png_pixel_data to a switch-case
Tero Marttila <terom@fixme.fi>
parents: 110
diff changeset
   417
                    break;
a31ffb59bc19 reformat png_pixel_data to a switch-case
Tero Marttila <terom@fixme.fi>
parents: 110
diff changeset
   418
                
a31ffb59bc19 reformat png_pixel_data to a switch-case
Tero Marttila <terom@fixme.fi>
parents: 110
diff changeset
   419
                default :
a31ffb59bc19 reformat png_pixel_data to a switch-case
Tero Marttila <terom@fixme.fi>
parents: 110
diff changeset
   420
                    // unknown
a31ffb59bc19 reformat png_pixel_data to a switch-case
Tero Marttila <terom@fixme.fi>
parents: 110
diff changeset
   421
                    return;
a31ffb59bc19 reformat png_pixel_data to a switch-case
Tero Marttila <terom@fixme.fi>
parents: 110
diff changeset
   422
            }
a31ffb59bc19 reformat png_pixel_data to a switch-case
Tero Marttila <terom@fixme.fi>
parents: 110
diff changeset
   423
a31ffb59bc19 reformat png_pixel_data to a switch-case
Tero Marttila <terom@fixme.fi>
parents: 110
diff changeset
   424
            // hrhr - assume our working data is valid (or we have 255 palette entries, so it doesn't matter...)
a31ffb59bc19 reformat png_pixel_data to a switch-case
Tero Marttila <terom@fixme.fi>
parents: 110
diff changeset
   425
            assert(p < header->num_palette);
a31ffb59bc19 reformat png_pixel_data to a switch-case
Tero Marttila <terom@fixme.fi>
parents: 110
diff changeset
   426
            
a31ffb59bc19 reformat png_pixel_data to a switch-case
Tero Marttila <terom@fixme.fi>
parents: 110
diff changeset
   427
            // reference data from palette
a31ffb59bc19 reformat png_pixel_data to a switch-case
Tero Marttila <terom@fixme.fi>
parents: 110
diff changeset
   428
            *outp = &header->palette[p];
a31ffb59bc19 reformat png_pixel_data to a switch-case
Tero Marttila <terom@fixme.fi>
parents: 110
diff changeset
   429
            
100
aee9d0b12fe9 void png_pixel_data, slight restructuring
Tero Marttila <terom@fixme.fi>
parents: 97
diff changeset
   430
            return;
aee9d0b12fe9 void png_pixel_data, slight restructuring
Tero Marttila <terom@fixme.fi>
parents: 97
diff changeset
   431
111
a31ffb59bc19 reformat png_pixel_data to a switch-case
Tero Marttila <terom@fixme.fi>
parents: 110
diff changeset
   432
        default :
a31ffb59bc19 reformat png_pixel_data to a switch-case
Tero Marttila <terom@fixme.fi>
parents: 110
diff changeset
   433
            // unknown pixel format
a31ffb59bc19 reformat png_pixel_data to a switch-case
Tero Marttila <terom@fixme.fi>
parents: 110
diff changeset
   434
            return;
100
aee9d0b12fe9 void png_pixel_data, slight restructuring
Tero Marttila <terom@fixme.fi>
parents: 97
diff changeset
   435
    }
aee9d0b12fe9 void png_pixel_data, slight restructuring
Tero Marttila <terom@fixme.fi>
parents: 97
diff changeset
   436
}
aee9d0b12fe9 void png_pixel_data, slight restructuring
Tero Marttila <terom@fixme.fi>
parents: 97
diff changeset
   437
aee9d0b12fe9 void png_pixel_data, slight restructuring
Tero Marttila <terom@fixme.fi>
parents: 97
diff changeset
   438
/**
56
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   439
 * Write scaled tile data
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   440
 */
70
35515b3a82b7 more constness for pt_png
Tero Marttila <terom@fixme.fi>
parents: 69
diff changeset
   441
static int pt_png_encode_zoomed (struct pt_png_img *img, const struct pt_png_header *header, const uint8_t *data, const struct pt_tile_info *ti)
56
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   442
{
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   443
    // size of the image data in px
127
df89d13f2354 invert zl meaning; zl=0 is 100%, zl=+n is zoomed out
Tero Marttila <terom@fixme.fi>
parents: 111
diff changeset
   444
    size_t data_width = scale_by_zoom_factor(ti->width, ti->zoom);
df89d13f2354 invert zl meaning; zl=0 is 100%, zl=+n is zoomed out
Tero Marttila <terom@fixme.fi>
parents: 111
diff changeset
   445
    size_t data_height = scale_by_zoom_factor(ti->height, ti->zoom);
56
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   446
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   447
    // input pixels per output pixel
127
df89d13f2354 invert zl meaning; zl=0 is 100%, zl=+n is zoomed out
Tero Marttila <terom@fixme.fi>
parents: 111
diff changeset
   448
    size_t pixel_size = scale_by_zoom_factor(1, ti->zoom);
56
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   449
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   450
    // bytes per output pixel
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   451
    size_t pixel_bytes = 3;
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   452
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   453
    // size of the output tile in px
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   454
    size_t row_width = ti->width;
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   455
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   456
    // size of an output row in bytes (RGB)
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   457
    size_t row_bytes = row_width * 3;
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   458
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   459
    // buffer to hold output rows
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   460
    uint8_t *row_buf;
100
aee9d0b12fe9 void png_pixel_data, slight restructuring
Tero Marttila <terom@fixme.fi>
parents: 97
diff changeset
   461
                
108
b81d2fcfa446 handle the png_color as a pointer in png_pixel_data
Tero Marttila <terom@fixme.fi>
parents: 100
diff changeset
   462
    // color entry for pixel
b81d2fcfa446 handle the png_color as a pointer in png_pixel_data
Tero Marttila <terom@fixme.fi>
parents: 100
diff changeset
   463
    const png_color *c = &header->palette[0];
56
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   464
    
69
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
   465
    // only supports zooming out...
127
df89d13f2354 invert zl meaning; zl=0 is 100%, zl=+n is zoomed out
Tero Marttila <terom@fixme.fi>
parents: 111
diff changeset
   466
    if (ti->zoom < 0)
86
d4a62899587f PT_ERR_TILE_DIM and PT_ERR_TILE_ZOOM
Tero Marttila <terom@fixme.fi>
parents: 84
diff changeset
   467
        RETURN_ERROR(PT_ERR_TILE_ZOOM);
56
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   468
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   469
    if ((row_buf = malloc(row_bytes)) == NULL)
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   470
        RETURN_ERROR(PT_ERR_MEM);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   471
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   472
    // suppress warning...
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   473
    (void) data_height;
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   474
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   475
    // define pixel format: 8bpp RGB
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   476
    png_set_IHDR(img->png, img->info, ti->width, ti->height, 8, PNG_COLOR_TYPE_RGB,
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   477
            PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   478
    );
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   479
    
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   480
    // write meta-info
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   481
    png_write_info(img->png, img->info);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   482
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   483
    // ...each output row
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   484
    for (size_t out_row = 0; out_row < ti->height; out_row++) {
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   485
        memset(row_buf, 0, row_bytes);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   486
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   487
        // ...includes pixels starting from this row.
127
df89d13f2354 invert zl meaning; zl=0 is 100%, zl=+n is zoomed out
Tero Marttila <terom@fixme.fi>
parents: 111
diff changeset
   488
        size_t in_row_offset = ti->y + scale_by_zoom_factor(out_row, ti->zoom);
56
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   489
        
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   490
        // ...each out row includes pixel_size in rows
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   491
        for (size_t in_row = in_row_offset; in_row < in_row_offset + pixel_size && in_row < header->height; in_row++) {
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   492
            // and includes each input pixel
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   493
            for (size_t in_col = ti->x; in_col < ti->x + data_width && in_col < header->width; in_col++) {
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   494
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   495
                // ...for this output pixel
127
df89d13f2354 invert zl meaning; zl=0 is 100%, zl=+n is zoomed out
Tero Marttila <terom@fixme.fi>
parents: 111
diff changeset
   496
                size_t out_col = scale_by_zoom_factor(in_col - ti->x, -ti->zoom);
56
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   497
                
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   498
                // get pixel RGB data
100
aee9d0b12fe9 void png_pixel_data, slight restructuring
Tero Marttila <terom@fixme.fi>
parents: 97
diff changeset
   499
                png_pixel_data(&c, header, data, in_row, in_col);
56
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   500
                
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   501
                // average the RGB data        
108
b81d2fcfa446 handle the png_color as a pointer in png_pixel_data
Tero Marttila <terom@fixme.fi>
parents: 100
diff changeset
   502
                ADD_AVG(row_buf[out_col * pixel_bytes + 0], c->red);
b81d2fcfa446 handle the png_color as a pointer in png_pixel_data
Tero Marttila <terom@fixme.fi>
parents: 100
diff changeset
   503
                ADD_AVG(row_buf[out_col * pixel_bytes + 1], c->green);
b81d2fcfa446 handle the png_color as a pointer in png_pixel_data
Tero Marttila <terom@fixme.fi>
parents: 100
diff changeset
   504
                ADD_AVG(row_buf[out_col * pixel_bytes + 2], c->blue);
56
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   505
            }
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   506
        }
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   507
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   508
        // output
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   509
        png_write_row(img->png, row_buf);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   510
    }
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   511
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   512
    // done
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   513
    return 0;
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   514
}
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   515
70
35515b3a82b7 more constness for pt_png
Tero Marttila <terom@fixme.fi>
parents: 69
diff changeset
   516
int pt_png_tile (const struct pt_png_header *header, const uint8_t *data, struct pt_tile *tile)
56
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   517
{
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   518
    struct pt_png_img _img, *img = &_img;
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   519
    struct pt_tile_info *ti = &tile->info;
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   520
    int err;
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   521
69
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
   522
    // init img
84
9cc49917ebac fix pt_png_tile img init
Tero Marttila <terom@fixme.fi>
parents: 70
diff changeset
   523
    memset(img, 0, sizeof(*img));
69
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
   524
56
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   525
    // check within bounds
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   526
    if (ti->x >= header->width || ti->y >= header->height)
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   527
        // completely outside
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   528
        RETURN_ERROR(PT_ERR_TILE_CLIP);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   529
    
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   530
    // open PNG writer
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   531
    if ((img->png = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL)) == NULL)
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   532
        JUMP_SET_ERROR(err, PT_ERR_PNG_CREATE);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   533
    
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   534
    if ((img->info = png_create_info_struct(img->png)) == NULL)
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   535
        JUMP_SET_ERROR(err, PT_ERR_PNG_CREATE);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   536
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   537
    // libpng error trap
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   538
    if (setjmp(png_jmpbuf(img->png)))
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   539
        JUMP_SET_ERROR(err, PT_ERR_PNG);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   540
 
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   541
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   542
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   543
    // setup output I/O
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   544
    switch (tile->out_type) {
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   545
        case PT_TILE_OUT_FILE:
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   546
            // use default FILE* operation
69
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
   547
            // do NOT store in img->fh
56
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   548
            png_init_io(img->png, tile->out.file);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   549
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   550
            break;
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   551
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   552
        case PT_TILE_OUT_MEM:
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   553
            // use pt_tile_mem struct via pt_png_mem_* callbacks
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   554
            png_set_write_fn(img->png, &tile->out.mem, pt_png_mem_write, pt_png_mem_flush);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   555
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   556
            break;
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   557
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   558
        default:
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   559
            FATAL("tile->out_type: %d", tile->out_type);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   560
    }
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   561
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   562
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   563
  
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   564
    // unscaled or scaled?
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   565
    if (ti->zoom)
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   566
        err = pt_png_encode_zoomed(img, header, data, ti);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   567
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   568
    else
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   569
        err = pt_png_encode_unzoomed(img, header, data, ti);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   570
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   571
    if (err)
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   572
        goto error;
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   573
    
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   574
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   575
    // flush remaining output
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   576
    png_write_flush(img->png);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   577
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   578
    // done
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   579
    png_write_end(img->png, img->info);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   580
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   581
error:
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   582
    // cleanup
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   583
    pt_png_release_write(img);
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   584
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   585
    return err;
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   586
}
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   587
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   588
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   589
void pt_png_release_read (struct pt_png_img *img)
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   590
{
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   591
    png_destroy_read_struct(&img->png, &img->info, NULL);
69
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
   592
    
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
   593
    // close possible filehandle
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
   594
    if (img->fh) {
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
   595
        if (fclose(img->fh))
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
   596
            log_warn_errno("fclose");
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
   597
    }
56
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   598
}
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   599
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   600
void pt_png_release_write (struct pt_png_img *img)
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   601
{
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   602
    png_destroy_write_struct(&img->png, &img->info);
69
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
   603
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
   604
    // close possible filehandle
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
   605
    if (img->fh) {
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
   606
        if (fclose(img->fh))
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
   607
            log_warn_errno("fclose");
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
   608
    }
1d188aa94aee pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents: 61
diff changeset
   609
56
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   610
}
d5e3089906da major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   611