author | Tero Marttila <terom@fixme.fi> |
Mon, 25 Jan 2010 04:34:02 +0200 | |
changeset 88 | 5cc2d044d368 |
parent 86 | d4a62899587f |
child 97 | 84952fa708d4 |
permissions | -rw-r--r-- |
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 |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
6 |
#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
|
7 |
|
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 |
#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
|
10 |
|
69
1d188aa94aee
pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents:
61
diff
changeset
|
11 |
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
|
12 |
{ |
1d188aa94aee
pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents:
61
diff
changeset
|
13 |
FILE *fp; |
1d188aa94aee
pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents:
61
diff
changeset
|
14 |
uint8_t header[8]; |
1d188aa94aee
pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents:
61
diff
changeset
|
15 |
int ret; |
1d188aa94aee
pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents:
61
diff
changeset
|
16 |
|
1d188aa94aee
pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents:
61
diff
changeset
|
17 |
// fopen |
1d188aa94aee
pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents:
61
diff
changeset
|
18 |
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
|
19 |
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
|
20 |
|
1d188aa94aee
pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents:
61
diff
changeset
|
21 |
// read |
1d188aa94aee
pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents:
61
diff
changeset
|
22 |
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
|
23 |
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
|
24 |
|
1d188aa94aee
pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents:
61
diff
changeset
|
25 |
// compare signature |
1d188aa94aee
pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents:
61
diff
changeset
|
26 |
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
|
27 |
// not a PNG file |
1d188aa94aee
pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents:
61
diff
changeset
|
28 |
ret = 1; |
1d188aa94aee
pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents:
61
diff
changeset
|
29 |
|
1d188aa94aee
pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents:
61
diff
changeset
|
30 |
else |
1d188aa94aee
pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents:
61
diff
changeset
|
31 |
// valid PNG file |
1d188aa94aee
pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents:
61
diff
changeset
|
32 |
ret = 0; |
1d188aa94aee
pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents:
61
diff
changeset
|
33 |
|
1d188aa94aee
pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents:
61
diff
changeset
|
34 |
error: |
1d188aa94aee
pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents:
61
diff
changeset
|
35 |
// cleanup |
1d188aa94aee
pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents:
61
diff
changeset
|
36 |
fclose(fp); |
1d188aa94aee
pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents:
61
diff
changeset
|
37 |
|
1d188aa94aee
pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents:
61
diff
changeset
|
38 |
return ret; |
1d188aa94aee
pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents:
61
diff
changeset
|
39 |
} |
1d188aa94aee
pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents:
61
diff
changeset
|
40 |
|
56
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
41 |
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
|
42 |
{ |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
43 |
int err; |
69
1d188aa94aee
pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents:
61
diff
changeset
|
44 |
|
1d188aa94aee
pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents:
61
diff
changeset
|
45 |
// init |
1d188aa94aee
pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents:
61
diff
changeset
|
46 |
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
|
47 |
|
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
48 |
// open I/O |
69
1d188aa94aee
pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents:
61
diff
changeset
|
49 |
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
|
50 |
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
|
51 |
|
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
52 |
// 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
|
53 |
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
|
54 |
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
|
55 |
|
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
56 |
// 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
|
57 |
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
|
58 |
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
|
59 |
|
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
60 |
// 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
|
61 |
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
|
62 |
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
|
63 |
|
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
64 |
// 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
|
65 |
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
|
66 |
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
|
67 |
|
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 |
// 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
|
70 |
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
|
71 |
|
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
72 |
// 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
|
73 |
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
|
74 |
|
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
75 |
|
69
1d188aa94aee
pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents:
61
diff
changeset
|
76 |
// 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
|
77 |
return 0; |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
78 |
|
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
79 |
error: |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
80 |
// cleanup |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
81 |
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
|
82 |
|
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
83 |
return err; |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
84 |
} |
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 |
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
|
87 |
{ |
69
1d188aa94aee
pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents:
61
diff
changeset
|
88 |
// 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
|
89 |
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
|
90 |
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
|
91 |
|
1d188aa94aee
pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents:
61
diff
changeset
|
92 |
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
|
93 |
} |
1d188aa94aee
pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents:
61
diff
changeset
|
94 |
|
56
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
95 |
|
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
96 |
// initialize |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
97 |
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
|
98 |
|
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
99 |
// 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
|
100 |
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
|
101 |
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
|
102 |
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
|
103 |
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
|
104 |
|
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
105 |
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
|
106 |
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
|
107 |
); |
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 |
// 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
|
110 |
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
|
111 |
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
|
112 |
|
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
113 |
// 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
|
114 |
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
|
115 |
|
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
116 |
// 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
|
117 |
// 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
|
118 |
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
|
119 |
|
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
120 |
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
|
121 |
|
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
122 |
// palette etc. |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
123 |
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
|
124 |
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
|
125 |
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
|
126 |
|
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
127 |
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
|
128 |
// 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
|
129 |
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
|
130 |
|
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
131 |
// 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
|
132 |
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
|
133 |
|
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
134 |
// copy |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
135 |
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
|
136 |
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
|
137 |
|
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
138 |
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
|
139 |
} |
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 |
// 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
|
142 |
*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
|
143 |
|
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
144 |
return 0; |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
145 |
} |
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 |
* 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
|
149 |
*/ |
61
31650ef395d3
use pt_png_decode_direct if no background color is set..
Tero Marttila <terom@fixme.fi>
parents:
56
diff
changeset
|
150 |
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
|
151 |
{ |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
152 |
// 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
|
153 |
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
|
154 |
// 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
|
155 |
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
|
156 |
} |
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 |
return 0; |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
159 |
} |
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 |
* 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
|
163 |
*/ |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
164 |
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
|
165 |
{ |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
166 |
// 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
|
167 |
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
|
168 |
|
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
169 |
// alloc |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
170 |
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
|
171 |
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
|
172 |
|
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
173 |
// 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
|
174 |
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
|
175 |
// 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
|
176 |
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
|
177 |
|
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
178 |
// 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
|
179 |
// ...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
|
180 |
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
|
181 |
// 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
|
182 |
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
|
183 |
|
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
184 |
// ...each pixel |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
185 |
for ( |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
186 |
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
|
187 |
|
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
188 |
// 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
|
189 |
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
|
190 |
|
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
191 |
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
|
192 |
) { |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
193 |
// 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
|
194 |
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
|
195 |
// differs |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
196 |
memcpy( |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
197 |
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
|
198 |
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
|
199 |
block_size |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
200 |
); |
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 |
// 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
|
203 |
break; |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
204 |
} |
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 |
// 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
|
208 |
continue; |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
209 |
} |
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 |
return 0; |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
213 |
} |
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 |
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
|
216 |
{ |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
217 |
int err; |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
218 |
|
61
31650ef395d3
use pt_png_decode_direct if no background color is set..
Tero Marttila <terom@fixme.fi>
parents:
56
diff
changeset
|
219 |
// decode |
31650ef395d3
use pt_png_decode_direct if no background color is set..
Tero Marttila <terom@fixme.fi>
parents:
56
diff
changeset
|
220 |
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
|
221 |
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
|
222 |
|
31650ef395d3
use pt_png_decode_direct if no background color is set..
Tero Marttila <terom@fixme.fi>
parents:
56
diff
changeset
|
223 |
else |
31650ef395d3
use pt_png_decode_direct if no background color is set..
Tero Marttila <terom@fixme.fi>
parents:
56
diff
changeset
|
224 |
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
|
225 |
|
31650ef395d3
use pt_png_decode_direct if no background color is set..
Tero Marttila <terom@fixme.fi>
parents:
56
diff
changeset
|
226 |
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
|
227 |
return err; |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
228 |
|
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
229 |
// 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
|
230 |
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
|
231 |
|
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
232 |
return 0; |
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 |
|
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
235 |
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
|
236 |
{ |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
237 |
// 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
|
238 |
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
|
239 |
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
|
240 |
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
|
241 |
|
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
242 |
return 0; |
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 |
|
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 |
* 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
|
247 |
*/ |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
248 |
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
|
249 |
{ |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
250 |
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
|
251 |
int err; |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
252 |
|
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
253 |
// 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
|
254 |
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
|
255 |
// 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
|
256 |
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
|
257 |
} |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
258 |
|
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 |
* 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
|
261 |
*/ |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
262 |
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
|
263 |
{ |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
264 |
// no-op |
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 |
|
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 |
* 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
|
270 |
*/ |
70 | 271 |
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
|
272 |
{ |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
273 |
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
|
274 |
} |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
275 |
|
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 |
* Fill in a clipped region of \a width_px pixels at the given row segment |
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 |
static inline void tile_row_fill_clip (const struct pt_png_header *header, png_byte *row, size_t width_px) |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
280 |
{ |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
281 |
// XXX: use a configureable background color, or full transparency? |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
282 |
memset(row, /* 0xd7 */ 0x00, width_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
|
283 |
} |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
284 |
|
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
285 |
/** |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
286 |
* 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
|
287 |
*/ |
70 | 288 |
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
|
289 |
{ |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
290 |
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
|
291 |
// write data directly |
70 | 292 |
// missing const... |
293 |
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
|
294 |
|
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
295 |
return 0; |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
296 |
} |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
297 |
|
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
298 |
/** |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
299 |
* 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
|
300 |
*/ |
70 | 301 |
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
|
302 |
{ |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
303 |
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
|
304 |
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
|
305 |
|
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
306 |
// 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
|
307 |
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
|
308 |
|
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
309 |
|
69
1d188aa94aee
pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents:
61
diff
changeset
|
310 |
// 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
|
311 |
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
|
312 |
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
|
313 |
|
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
314 |
|
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
315 |
// 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
|
316 |
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
|
317 |
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
|
318 |
|
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
319 |
// 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
|
320 |
// 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
|
321 |
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
|
322 |
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
|
323 |
|
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
324 |
// 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
|
325 |
// 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
|
326 |
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
|
327 |
// 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
|
328 |
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
|
329 |
|
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
330 |
// 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
|
331 |
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
|
332 |
|
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
333 |
// write |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
334 |
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
|
335 |
} |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
336 |
|
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
337 |
// 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
|
338 |
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
|
339 |
|
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
340 |
// 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
|
341 |
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
|
342 |
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
|
343 |
|
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
344 |
// ok |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
345 |
return 0; |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
346 |
} |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
347 |
|
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
348 |
static size_t scale_by_zoom_factor (size_t value, int z) |
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 |
if (z > 0) |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
351 |
return value << z; |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
352 |
|
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
353 |
else if (z < 0) |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
354 |
return value >> -z; |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
355 |
|
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
356 |
else |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
357 |
return value; |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
358 |
} |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
359 |
|
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
360 |
#define ADD_AVG(l, r) (l) = ((l) + (r)) / 2 |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
361 |
|
70 | 362 |
static int png_pixel_data (png_color *out, 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
|
363 |
{ |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
364 |
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
|
365 |
// palette entry number |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
366 |
int p; |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
367 |
|
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
368 |
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
|
369 |
p = *((uint8_t *) tile_row_col(header, data, row, col)); |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
370 |
else |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
371 |
return -1; |
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 |
if (p >= header->num_palette) |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
374 |
return -1; |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
375 |
|
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
376 |
// reference data from palette |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
377 |
*out = header->palette[p]; |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
378 |
|
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
379 |
return 0; |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
380 |
|
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
381 |
} else { |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
382 |
return -1; |
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 |
|
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
386 |
/** |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
387 |
* 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
|
388 |
*/ |
70 | 389 |
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
|
390 |
{ |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
391 |
int err; |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
392 |
|
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
393 |
// 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
|
394 |
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
|
395 |
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
|
396 |
); |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
397 |
|
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
398 |
// set palette? |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
399 |
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
|
400 |
// oops... missing const |
31650ef395d3
use pt_png_decode_direct if no background color is set..
Tero Marttila <terom@fixme.fi>
parents:
56
diff
changeset
|
401 |
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
|
402 |
|
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
403 |
// 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
|
404 |
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
|
405 |
|
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
406 |
// 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
|
407 |
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
|
408 |
|
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
409 |
// 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
|
410 |
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
|
411 |
// 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
|
412 |
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
|
413 |
|
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
414 |
else |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
415 |
// 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
|
416 |
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
|
417 |
|
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
418 |
return err; |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
419 |
} |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
420 |
|
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
421 |
/** |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
422 |
* 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
|
423 |
*/ |
70 | 424 |
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
|
425 |
{ |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
426 |
// size of the image data in px |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
427 |
size_t data_width = scale_by_zoom_factor(ti->width, -ti->zoom); |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
428 |
size_t data_height = scale_by_zoom_factor(ti->height, -ti->zoom); |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
429 |
|
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
430 |
// input pixels 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
|
431 |
size_t pixel_size = scale_by_zoom_factor(1, -ti->zoom); |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
432 |
|
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
433 |
// 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
|
434 |
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
|
435 |
|
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
436 |
// 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
|
437 |
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
|
438 |
|
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
439 |
// 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
|
440 |
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
|
441 |
|
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
442 |
// 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
|
443 |
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
|
444 |
|
69
1d188aa94aee
pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents:
61
diff
changeset
|
445 |
// only supports zooming out... |
56
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
446 |
if (ti->zoom >= 0) |
86
d4a62899587f
PT_ERR_TILE_DIM and PT_ERR_TILE_ZOOM
Tero Marttila <terom@fixme.fi>
parents:
84
diff
changeset
|
447 |
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
|
448 |
|
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
449 |
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
|
450 |
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
|
451 |
|
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
452 |
// suppress warning... |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
453 |
(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
|
454 |
|
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
455 |
// 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
|
456 |
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
|
457 |
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
|
458 |
); |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
459 |
|
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
460 |
// 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
|
461 |
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
|
462 |
|
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
463 |
// ...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
|
464 |
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
|
465 |
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
|
466 |
|
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
467 |
// ...includes pixels starting from this row. |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
468 |
size_t in_row_offset = ti->y + scale_by_zoom_factor(out_row, -ti->zoom); |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
469 |
|
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
470 |
// ...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
|
471 |
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
|
472 |
// 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
|
473 |
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
|
474 |
png_color c; |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
475 |
|
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
476 |
// ...for this output pixel |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
477 |
size_t out_col = scale_by_zoom_factor(in_col - ti->x, ti->zoom); |
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 |
// get pixel RGB data |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
480 |
if (png_pixel_data(&c, header, data, in_row, in_col)) |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
481 |
return -1; |
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 |
// average the RGB data |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
484 |
ADD_AVG(row_buf[out_col * pixel_bytes + 0], c.red); |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
485 |
ADD_AVG(row_buf[out_col * pixel_bytes + 1], c.green); |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
486 |
ADD_AVG(row_buf[out_col * pixel_bytes + 2], c.blue); |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
487 |
} |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
488 |
} |
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 |
// output |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
491 |
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
|
492 |
} |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
493 |
|
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
494 |
// done |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
495 |
return 0; |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
496 |
} |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
497 |
|
70 | 498 |
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
|
499 |
{ |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
500 |
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
|
501 |
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
|
502 |
int err; |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
503 |
|
69
1d188aa94aee
pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents:
61
diff
changeset
|
504 |
// init img |
84 | 505 |
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
|
506 |
|
56
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
507 |
// 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
|
508 |
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
|
509 |
// completely outside |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
510 |
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
|
511 |
|
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
512 |
// 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
|
513 |
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
|
514 |
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
|
515 |
|
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
516 |
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
|
517 |
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
|
518 |
|
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
519 |
// 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
|
520 |
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
|
521 |
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
|
522 |
|
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
523 |
|
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
524 |
|
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
525 |
// 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
|
526 |
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
|
527 |
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
|
528 |
// use default FILE* operation |
69
1d188aa94aee
pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents:
61
diff
changeset
|
529 |
// 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
|
530 |
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
|
531 |
|
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
532 |
break; |
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 |
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
|
535 |
// 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
|
536 |
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
|
537 |
|
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
538 |
break; |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
539 |
|
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
540 |
default: |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
541 |
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
|
542 |
} |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
543 |
|
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
544 |
|
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
545 |
|
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
546 |
// 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
|
547 |
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
|
548 |
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
|
549 |
|
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
550 |
else |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
551 |
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
|
552 |
|
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
553 |
if (err) |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
554 |
goto error; |
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 |
|
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
557 |
// 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
|
558 |
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
|
559 |
|
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
560 |
// done |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
561 |
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
|
562 |
|
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
563 |
error: |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
564 |
// cleanup |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
565 |
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
|
566 |
|
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
567 |
return err; |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
568 |
} |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
569 |
|
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 |
|
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
572 |
|
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 |
|
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
576 |
|
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 |
|
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
579 |
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
|
580 |
{ |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
581 |
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
|
582 |
|
1d188aa94aee
pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents:
61
diff
changeset
|
583 |
// close possible filehandle |
1d188aa94aee
pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents:
61
diff
changeset
|
584 |
if (img->fh) { |
1d188aa94aee
pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents:
61
diff
changeset
|
585 |
if (fclose(img->fh)) |
1d188aa94aee
pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents:
61
diff
changeset
|
586 |
log_warn_errno("fclose"); |
1d188aa94aee
pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents:
61
diff
changeset
|
587 |
} |
56
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 |
|
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
590 |
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
|
591 |
{ |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
592 |
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
|
593 |
|
1d188aa94aee
pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents:
61
diff
changeset
|
594 |
// close possible filehandle |
1d188aa94aee
pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents:
61
diff
changeset
|
595 |
if (img->fh) { |
1d188aa94aee
pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents:
61
diff
changeset
|
596 |
if (fclose(img->fh)) |
1d188aa94aee
pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents:
61
diff
changeset
|
597 |
log_warn_errno("fclose"); |
1d188aa94aee
pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents:
61
diff
changeset
|
598 |
} |
1d188aa94aee
pt_png_check, and fclose() pt_image_open_file
Tero Marttila <terom@fixme.fi>
parents:
61
diff
changeset
|
599 |
|
56
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
600 |
} |
d5e3089906da
major refactoring of pt_cache, split off all PNG processing into pt_png
Tero Marttila <terom@fixme.fi>
parents:
diff
changeset
|
601 |