webp-ffi 0.2.3 → 0.2.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5dc135cb052630588802ca113f8d11a18ccd0dfe
4
- data.tar.gz: 685b69ef56c9d2928ab5a6c2f1631f5675bb5796
3
+ metadata.gz: 34b1495b74a5385dd27950b6e4bc2f4e5391fa97
4
+ data.tar.gz: 90b299d673ff0c22afef51ffbb61d6fabd4733ae
5
5
  SHA512:
6
- metadata.gz: 4b38a77daf24a59aebe807b2444f2a8c601392f78d1d4bdac3363887268ecd2f647577c66bad6847b9dd4ebc147d53c81b5724da042107b4ec1712a427a39edc
7
- data.tar.gz: 56a5f00d3cc2b4719060d5e6b03684754d34451cab57a05ce2f476153631f386fd61ce39877f722e3e1ddf68eaf938eec8102672e307dee823ecd1bbbb9a6532
6
+ metadata.gz: fe4fd8a5a8b3fe9b741bc028c55f13272ff1e642961d88b9bc4bbcbf74b4554c0312617a0e13b3b106473846587d0d4cbee2a0ae0818347e0f471d91badee2f1
7
+ data.tar.gz: 7a7b54b518cee8bb959c6a074c4983991492ec1cce5192a8f915568d748f20ad7570581952dd5c1b09ce0e471d87104532ff42c6cb849413a05f6e6b0f89eba4
@@ -1 +1 @@
1
- 2.1.0
1
+ 2.1.2
@@ -5,7 +5,7 @@ rvm:
5
5
  - 1.9.2
6
6
  - 1.9.3
7
7
  - 2.0.0
8
- - 2.1.0
8
+ - 2.1.2
9
9
  - jruby-19mode
10
10
  - rbx-19mode
11
11
  - ruby-head
@@ -1,3 +1,7 @@
1
+ ## v0.2.4
2
+
3
+ * DRY C code and split into files each read/write formats
4
+
1
5
  ## v0.2.3
2
6
 
3
7
  * Fix jpg read in C code
@@ -0,0 +1,80 @@
1
+ #include "./jpegdec.h"
2
+
3
+ #include <stdio.h>
4
+ #include <jpeglib.h>
5
+ #include <setjmp.h>
6
+ #include <stdlib.h>
7
+ #include <string.h>
8
+
9
+ struct my_error_mgr {
10
+ struct jpeg_error_mgr pub;
11
+ jmp_buf setjmp_buffer;
12
+ };
13
+
14
+ static void my_error_exit(j_common_ptr dinfo) {
15
+ struct my_error_mgr* myerr = (struct my_error_mgr*) dinfo->err;
16
+ (*dinfo->err->output_message) (dinfo);
17
+ longjmp(myerr->setjmp_buffer, 1);
18
+ }
19
+
20
+ int UtilReadJPEG(FILE* in_file, WebPPicture* const pic) {
21
+ int ok = 0;
22
+ int stride, width, height;
23
+ uint8_t* rgb = NULL;
24
+ struct jpeg_decompress_struct dinfo;
25
+ struct my_error_mgr jerr;
26
+ JSAMPROW buffer[1];
27
+
28
+ dinfo.err = jpeg_std_error(&jerr.pub);
29
+ jerr.pub.error_exit = my_error_exit;
30
+
31
+ if (setjmp(jerr.setjmp_buffer)) {
32
+ Error:
33
+ jpeg_destroy_decompress(&dinfo);
34
+ goto End;
35
+ }
36
+
37
+ jpeg_create_decompress(&dinfo);
38
+ jpeg_stdio_src(&dinfo, in_file);
39
+ jpeg_read_header(&dinfo, TRUE);
40
+
41
+ dinfo.out_color_space = JCS_RGB;
42
+ dinfo.do_fancy_upsampling = TRUE;
43
+
44
+ jpeg_start_decompress(&dinfo);
45
+
46
+ if (dinfo.output_components != 3) {
47
+ goto Error;
48
+ }
49
+
50
+ width = dinfo.output_width;
51
+ height = dinfo.output_height;
52
+ stride = dinfo.output_width * dinfo.output_components * sizeof(*rgb);
53
+
54
+ rgb = (uint8_t*)malloc(stride * height);
55
+ if (rgb == NULL) {
56
+ goto End;
57
+ }
58
+ buffer[0] = (JSAMPLE*)rgb;
59
+
60
+ while (dinfo.output_scanline < dinfo.output_height) {
61
+ if (jpeg_read_scanlines(&dinfo, buffer, 1) != 1) {
62
+ goto End;
63
+ }
64
+ buffer[0] += stride;
65
+ }
66
+
67
+ jpeg_finish_decompress(&dinfo);
68
+ jpeg_destroy_decompress(&dinfo);
69
+
70
+ // WebP conversion.
71
+ pic->width = width;
72
+ pic->height = height;
73
+ ok = WebPPictureImportRGB(pic, rgb, stride);
74
+ if (!ok) goto Error;
75
+
76
+ End:
77
+ free(rgb);
78
+ return ok;
79
+ }
80
+
@@ -0,0 +1,17 @@
1
+ #include <stdio.h>
2
+
3
+ #include "webp/encode.h"
4
+ #include "webp/decode.h"
5
+
6
+ #ifdef __cplusplus
7
+ extern "C" {
8
+ #endif
9
+
10
+ // Reads a JPEG from 'in_file', returning the decoded output in 'pic'.
11
+ // The output is RGB.
12
+ // Returns true on success.
13
+ int UtilReadJPEG(FILE* in_file, struct WebPPicture* const pic);
14
+
15
+ #ifdef __cplusplus
16
+ } // extern "C"
17
+ #endif
@@ -0,0 +1,212 @@
1
+ #include "./pngdec.h"
2
+
3
+ #include <assert.h>
4
+ #include <stdio.h>
5
+ #include <png.h>
6
+ #include <setjmp.h> // note: this must be included *after* png.h
7
+ #include <stdlib.h>
8
+ #include <string.h>
9
+
10
+ static void PNGAPI error_function(png_structp png, png_const_charp dummy) {
11
+ (void)dummy; // remove variable-unused warning
12
+ longjmp(png_jmpbuf(png), 1);
13
+ }
14
+
15
+ int UtilReadPNG(FILE* in_file, WebPPicture* const pic, int keep_alpha) {
16
+ png_structp png;
17
+ png_infop info = NULL;
18
+ png_infop end_info = NULL;
19
+ int color_type, bit_depth, interlaced;
20
+ int has_alpha;
21
+ int num_passes;
22
+ int p;
23
+ int ok = 0;
24
+ png_uint_32 width, height, y;
25
+ int stride;
26
+ uint8_t* rgb = NULL;
27
+
28
+ png = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
29
+ if (png == NULL) {
30
+ goto End;
31
+ }
32
+
33
+ png_set_error_fn(png, 0, error_function, NULL);
34
+ if (setjmp(png_jmpbuf(png))) {
35
+ Error:
36
+ png_destroy_read_struct(&png, &info, &end_info);
37
+ goto End;
38
+ }
39
+
40
+ info = png_create_info_struct(png);
41
+ if (info == NULL) goto Error;
42
+ end_info = png_create_info_struct(png);
43
+ if (end_info == NULL) goto Error;
44
+
45
+ png_init_io(png, in_file);
46
+ png_read_info(png, info);
47
+ if (!png_get_IHDR(png, info,
48
+ &width, &height, &bit_depth, &color_type, &interlaced,
49
+ NULL, NULL)) goto Error;
50
+
51
+ png_set_strip_16(png);
52
+ png_set_packing(png);
53
+ if (color_type == PNG_COLOR_TYPE_PALETTE) png_set_palette_to_rgb(png);
54
+ if (color_type == PNG_COLOR_TYPE_GRAY ||
55
+ color_type == PNG_COLOR_TYPE_GRAY_ALPHA) {
56
+ if (bit_depth < 8) {
57
+ png_set_expand_gray_1_2_4_to_8(png);
58
+ }
59
+ png_set_gray_to_rgb(png);
60
+ }
61
+ if (png_get_valid(png, info, PNG_INFO_tRNS)) {
62
+ png_set_tRNS_to_alpha(png);
63
+ has_alpha = 1;
64
+ } else {
65
+ has_alpha = !!(color_type & PNG_COLOR_MASK_ALPHA);
66
+ }
67
+
68
+ if (!keep_alpha) {
69
+ png_set_strip_alpha(png);
70
+ has_alpha = 0;
71
+ }
72
+
73
+ num_passes = png_set_interlace_handling(png);
74
+ png_read_update_info(png, info);
75
+ stride = (has_alpha ? 4 : 3) * width * sizeof(*rgb);
76
+ rgb = (uint8_t*)malloc(stride * height);
77
+ if (rgb == NULL) goto Error;
78
+ for (p = 0; p < num_passes; ++p) {
79
+ for (y = 0; y < height; ++y) {
80
+ png_bytep row = rgb + y * stride;
81
+ png_read_rows(png, &row, NULL, 1);
82
+ }
83
+ }
84
+ png_read_end(png, end_info);
85
+ png_destroy_read_struct(&png, &info, &end_info);
86
+
87
+ pic->width = width;
88
+ pic->height = height;
89
+ pic->use_argb = 1;
90
+ ok = has_alpha ? WebPPictureImportRGBA(pic, rgb, stride)
91
+ : WebPPictureImportRGB(pic, rgb, stride);
92
+
93
+ if (!ok) {
94
+ goto Error;
95
+ }
96
+
97
+ End:
98
+ free(rgb);
99
+ return ok;
100
+ }
101
+
102
+
103
+
104
+
105
+
106
+ int UtilWritePNG(FILE* out_file, const WebPDecBuffer* const buffer) {
107
+ const uint32_t width = buffer->width;
108
+ const uint32_t height = buffer->height;
109
+ unsigned char* const rgb = buffer->u.RGBA.rgba;
110
+ const int stride = buffer->u.RGBA.stride;
111
+ const int has_alpha = (buffer->colorspace == MODE_RGBA);
112
+ png_structp png;
113
+ png_infop info;
114
+ png_uint_32 y;
115
+
116
+ png = png_create_write_struct(PNG_LIBPNG_VER_STRING,
117
+ NULL, error_function, NULL);
118
+ if (png == NULL) {
119
+ return 0;
120
+ }
121
+ info = png_create_info_struct(png);
122
+ if (info == NULL) {
123
+ png_destroy_write_struct(&png, NULL);
124
+ return 0;
125
+ }
126
+ if (setjmp(png_jmpbuf(png))) {
127
+ png_destroy_write_struct(&png, &info);
128
+ return 0;
129
+ }
130
+ png_init_io(png, out_file);
131
+ png_set_IHDR(png, info, width, height, 8,
132
+ has_alpha ? PNG_COLOR_TYPE_RGBA : PNG_COLOR_TYPE_RGB,
133
+ PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT,
134
+ PNG_FILTER_TYPE_DEFAULT);
135
+ png_write_info(png, info);
136
+ for (y = 0; y < height; ++y) {
137
+ png_bytep row = rgb + y * stride;
138
+ png_write_rows(png, &row, 1);
139
+ }
140
+ png_write_end(png, info);
141
+ png_destroy_write_struct(&png, &info);
142
+ return 1;
143
+ }
144
+
145
+
146
+ int UtilWritePPM(FILE* fout, const WebPDecBuffer* const buffer, int alpha) {
147
+ const uint32_t width = buffer->width;
148
+ const uint32_t height = buffer->height;
149
+ const unsigned char* const rgb = buffer->u.RGBA.rgba;
150
+ const int stride = buffer->u.RGBA.stride;
151
+ const size_t bytes_per_px = alpha ? 4 : 3;
152
+ uint32_t y;
153
+
154
+ if (alpha) {
155
+ fprintf(fout, "P7\nWIDTH %d\nHEIGHT %d\nDEPTH 4\nMAXVAL 255\n"
156
+ "TUPLTYPE RGB_ALPHA\nENDHDR\n", width, height);
157
+ } else {
158
+ fprintf(fout, "P6\n%d %d\n255\n", width, height);
159
+ }
160
+ for (y = 0; y < height; ++y) {
161
+ if (fwrite(rgb + y * stride, width, bytes_per_px, fout) != bytes_per_px) {
162
+ return 0;
163
+ }
164
+ }
165
+ return 1;
166
+ }
167
+
168
+ int UtilWriteAlphaPlane(FILE* fout, const WebPDecBuffer* const buffer) {
169
+ const uint32_t width = buffer->width;
170
+ const uint32_t height = buffer->height;
171
+ const unsigned char* const a = buffer->u.YUVA.a;
172
+ const int a_stride = buffer->u.YUVA.a_stride;
173
+ uint32_t y;
174
+ assert(a != NULL);
175
+ fprintf(fout, "P5\n%d %d\n255\n", width, height);
176
+ for (y = 0; y < height; ++y) {
177
+ if (fwrite(a + y * a_stride, width, 1, fout) != 1) {
178
+ return 0;
179
+ }
180
+ }
181
+ return 1;
182
+ }
183
+
184
+ int UtilWritePGM(FILE* fout, const WebPDecBuffer* const buffer) {
185
+ const int width = buffer->width;
186
+ const int height = buffer->height;
187
+ const WebPYUVABuffer* const yuv = &buffer->u.YUVA;
188
+ // Save a grayscale PGM file using the IMC4 layout
189
+ // (http://www.fourcc.org/yuv.php#IMC4). This is a very
190
+ // convenient format for viewing the samples, esp. for
191
+ // odd dimensions.
192
+ int ok = 1;
193
+ int y;
194
+ const int uv_width = (width + 1) / 2;
195
+ const int uv_height = (height + 1) / 2;
196
+ const int out_stride = (width + 1) & ~1;
197
+ const int a_height = yuv->a ? height : 0;
198
+ fprintf(fout, "P5\n%d %d\n255\n", out_stride, height + uv_height + a_height);
199
+ for (y = 0; ok && y < height; ++y) {
200
+ ok &= (fwrite(yuv->y + y * yuv->y_stride, width, 1, fout) == 1);
201
+ if (width & 1) fputc(0, fout); // padding byte
202
+ }
203
+ for (y = 0; ok && y < uv_height; ++y) {
204
+ ok &= (fwrite(yuv->u + y * yuv->u_stride, uv_width, 1, fout) == 1);
205
+ ok &= (fwrite(yuv->v + y * yuv->v_stride, uv_width, 1, fout) == 1);
206
+ }
207
+ for (y = 0; ok && y < a_height; ++y) {
208
+ ok &= (fwrite(yuv->a + y * yuv->a_stride, width, 1, fout) == 1);
209
+ if (width & 1) fputc(0, fout); // padding byte
210
+ }
211
+ return ok;
212
+ }
@@ -0,0 +1,24 @@
1
+ #include <stdio.h>
2
+ #include <stdlib.h>
3
+
4
+ #include "webp/encode.h"
5
+ #include "webp/decode.h"
6
+
7
+ #ifdef __cplusplus
8
+ extern "C" {
9
+ #endif
10
+
11
+ // Reads a PNG from 'in_file', returning the decoded output in 'pic'.
12
+ // If 'keep_alpha' is true and the PNG has an alpha channel, the output is RGBA
13
+ // otherwise it will be RGB.
14
+ // Returns true on success.
15
+ int UtilReadPNG(FILE* in_file, struct WebPPicture* const pic, int keep_alpha);
16
+
17
+ int UtilWritePNG(FILE* out_file, const WebPDecBuffer* const buffer);
18
+ int UtilWritePPM(FILE* fout, const WebPDecBuffer* const buffer, int alpha);
19
+ int UtilWriteAlphaPlane(FILE* fout, const WebPDecBuffer* const buffer);
20
+ int UtilWritePGM(FILE* fout, const WebPDecBuffer* const buffer);
21
+
22
+ #ifdef __cplusplus
23
+ } // extern "C"
24
+ #endif
@@ -0,0 +1,197 @@
1
+ #include "./tiffdec.h"
2
+
3
+ #include <tiffio.h>
4
+
5
+ int UtilReadTIFF(const char* const filename,
6
+ WebPPicture* const pic, int keep_alpha) {
7
+ TIFF* const tif = TIFFOpen(filename, "r");
8
+ uint32 width, height;
9
+ uint32* raster;
10
+ int ok = 0;
11
+ int dircount = 1;
12
+
13
+ if (tif == NULL) {
14
+ //fprintf(stderr, "Error! Cannot open TIFF file '%s'\n", filename);
15
+ return 0;
16
+ }
17
+
18
+ while (TIFFReadDirectory(tif)) ++dircount;
19
+
20
+ if (dircount > 1) {
21
+ fprintf(stderr, "Warning: multi-directory TIFF files are not supported.\n"
22
+ "Only the first will be used, %d will be ignored.\n",
23
+ dircount - 1);
24
+ }
25
+
26
+ TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width);
27
+ TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height);
28
+ raster = (uint32*)_TIFFmalloc(width * height * sizeof(*raster));
29
+ if (raster != NULL) {
30
+ if (TIFFReadRGBAImageOriented(tif, width, height, raster,
31
+ ORIENTATION_TOPLEFT, 1)) {
32
+ const int stride = width * sizeof(*raster);
33
+ pic->width = width;
34
+ pic->height = height;
35
+ // TIFF data is ABGR
36
+ #ifdef __BIG_ENDIAN__
37
+ TIFFSwabArrayOfLong(raster, width * height);
38
+ #endif
39
+ ok = keep_alpha
40
+ ? WebPPictureImportRGBA(pic, (const uint8_t*)raster, stride)
41
+ : WebPPictureImportRGBX(pic, (const uint8_t*)raster, stride);
42
+ }
43
+ _TIFFfree(raster);
44
+ } else {
45
+ //fprintf(stderr, "Error allocating TIFF RGBA memory!\n");
46
+ }
47
+
48
+ if (ok && keep_alpha == 2) {
49
+ WebPCleanupTransparentArea(pic);
50
+ }
51
+
52
+ TIFFClose(tif);
53
+ return ok;
54
+ }
55
+
56
+
57
+
58
+ static void PutLE16(uint8_t* const dst, uint32_t value) {
59
+ dst[0] = (value >> 0) & 0xff;
60
+ dst[1] = (value >> 8) & 0xff;
61
+ }
62
+
63
+ static void PutLE32(uint8_t* const dst, uint32_t value) {
64
+ PutLE16(dst + 0, (value >> 0) & 0xffff);
65
+ PutLE16(dst + 2, (value >> 16) & 0xffff);
66
+ }
67
+
68
+
69
+ #define NUM_IFD_ENTRIES 15
70
+ #define EXTRA_DATA_SIZE 16
71
+ // 10b for signature/header + n * 12b entries + 4b for IFD terminator:
72
+ #define EXTRA_DATA_OFFSET (10 + 12 * NUM_IFD_ENTRIES + 4)
73
+ #define TIFF_HEADER_SIZE (EXTRA_DATA_OFFSET + EXTRA_DATA_SIZE)
74
+
75
+ int UtilWriteTIFF(FILE* fout, const WebPDecBuffer* const buffer) {
76
+ const int has_alpha = (buffer->colorspace != MODE_RGB);
77
+ const uint32_t width = buffer->width;
78
+ const uint32_t height = buffer->height;
79
+ const uint8_t* const rgba = buffer->u.RGBA.rgba;
80
+ const int stride = buffer->u.RGBA.stride;
81
+ const uint8_t bytes_per_px = has_alpha ? 4 : 3;
82
+ // For non-alpha case, we omit tag 0x152 (ExtraSamples).
83
+ const uint8_t num_ifd_entries = has_alpha ? NUM_IFD_ENTRIES
84
+ : NUM_IFD_ENTRIES - 1;
85
+ uint8_t tiff_header[TIFF_HEADER_SIZE] = {
86
+ 0x49, 0x49, 0x2a, 0x00, // little endian signature
87
+ 8, 0, 0, 0, // offset to the unique IFD that follows
88
+ // IFD (offset = 8). Entries must be written in increasing tag order.
89
+ num_ifd_entries, 0, // Number of entries in the IFD (12 bytes each).
90
+ 0x00, 0x01, 3, 0, 1, 0, 0, 0, 0, 0, 0, 0, // 10: Width (TBD)
91
+ 0x01, 0x01, 3, 0, 1, 0, 0, 0, 0, 0, 0, 0, // 22: Height (TBD)
92
+ 0x02, 0x01, 3, 0, bytes_per_px, 0, 0, 0, // 34: BitsPerSample: 8888
93
+ EXTRA_DATA_OFFSET + 0, 0, 0, 0,
94
+ 0x03, 0x01, 3, 0, 1, 0, 0, 0, 1, 0, 0, 0, // 46: Compression: none
95
+ 0x06, 0x01, 3, 0, 1, 0, 0, 0, 2, 0, 0, 0, // 58: Photometric: RGB
96
+ 0x11, 0x01, 4, 0, 1, 0, 0, 0, // 70: Strips offset:
97
+ TIFF_HEADER_SIZE, 0, 0, 0, // data follows header
98
+ 0x12, 0x01, 3, 0, 1, 0, 0, 0, 1, 0, 0, 0, // 82: Orientation: topleft
99
+ 0x15, 0x01, 3, 0, 1, 0, 0, 0, // 94: SamplesPerPixels
100
+ bytes_per_px, 0, 0, 0,
101
+ 0x16, 0x01, 3, 0, 1, 0, 0, 0, 0, 0, 0, 0, // 106: Rows per strip (TBD)
102
+ 0x17, 0x01, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, // 118: StripByteCount (TBD)
103
+ 0x1a, 0x01, 5, 0, 1, 0, 0, 0, // 130: X-resolution
104
+ EXTRA_DATA_OFFSET + 8, 0, 0, 0,
105
+ 0x1b, 0x01, 5, 0, 1, 0, 0, 0, // 142: Y-resolution
106
+ EXTRA_DATA_OFFSET + 8, 0, 0, 0,
107
+ 0x1c, 0x01, 3, 0, 1, 0, 0, 0, 1, 0, 0, 0, // 154: PlanarConfiguration
108
+ 0x28, 0x01, 3, 0, 1, 0, 0, 0, 2, 0, 0, 0, // 166: ResolutionUnit (inch)
109
+ 0x52, 0x01, 3, 0, 1, 0, 0, 0, 1, 0, 0, 0, // 178: ExtraSamples: rgbA
110
+ 0, 0, 0, 0, // 190: IFD terminator
111
+ // EXTRA_DATA_OFFSET:
112
+ 8, 0, 8, 0, 8, 0, 8, 0, // BitsPerSample
113
+ 72, 0, 0, 0, 1, 0, 0, 0 // 72 pixels/inch, for X/Y-resolution
114
+ };
115
+ uint32_t y;
116
+
117
+ // Fill placeholders in IFD:
118
+ PutLE32(tiff_header + 10 + 8, width);
119
+ PutLE32(tiff_header + 22 + 8, height);
120
+ PutLE32(tiff_header + 106 + 8, height);
121
+ PutLE32(tiff_header + 118 + 8, width * bytes_per_px * height);
122
+ if (!has_alpha) PutLE32(tiff_header + 178, 0); // IFD terminator
123
+
124
+ // write header
125
+ if (fwrite(tiff_header, sizeof(tiff_header), 1, fout) != 1) {
126
+ return 0;
127
+ }
128
+ // write pixel values
129
+ for (y = 0; y < height; ++y) {
130
+ if (fwrite(rgba + y * stride, bytes_per_px, width, fout) != width) {
131
+ return 0;
132
+ }
133
+ }
134
+
135
+ return 1;
136
+ }
137
+
138
+ #undef TIFF_HEADER_SIZE
139
+ #undef EXTRA_DATA_OFFSET
140
+ #undef EXTRA_DATA_SIZE
141
+ #undef NUM_IFD_ENTRIES
142
+
143
+ #define BMP_HEADER_SIZE 54
144
+ int UtilWriteBMP(FILE* fout, const WebPDecBuffer* const buffer) {
145
+ const int has_alpha = (buffer->colorspace != MODE_BGR);
146
+ const uint32_t width = buffer->width;
147
+ const uint32_t height = buffer->height;
148
+ const uint8_t* const rgba = buffer->u.RGBA.rgba;
149
+ const int stride = buffer->u.RGBA.stride;
150
+ const uint32_t bytes_per_px = has_alpha ? 4 : 3;
151
+ uint32_t y;
152
+ const uint32_t line_size = bytes_per_px * width;
153
+ const uint32_t bmp_stride = (line_size + 3) & ~3; // pad to 4
154
+ const uint32_t total_size = bmp_stride * height + BMP_HEADER_SIZE;
155
+ uint8_t bmp_header[BMP_HEADER_SIZE] = { 0 };
156
+
157
+ // bitmap file header
158
+ PutLE16(bmp_header + 0, 0x4d42); // signature 'BM'
159
+ PutLE32(bmp_header + 2, total_size); // size including header
160
+ PutLE32(bmp_header + 6, 0); // reserved
161
+ PutLE32(bmp_header + 10, BMP_HEADER_SIZE); // offset to pixel array
162
+ // bitmap info header
163
+ PutLE32(bmp_header + 14, 40); // DIB header size
164
+ PutLE32(bmp_header + 18, width); // dimensions
165
+ PutLE32(bmp_header + 22, -(int)height); // vertical flip!
166
+ PutLE16(bmp_header + 26, 1); // number of planes
167
+ PutLE16(bmp_header + 28, bytes_per_px * 8); // bits per pixel
168
+ PutLE32(bmp_header + 30, 0); // no compression (BI_RGB)
169
+ PutLE32(bmp_header + 34, 0); // image size (dummy)
170
+ PutLE32(bmp_header + 38, 2400); // x pixels/meter
171
+ PutLE32(bmp_header + 42, 2400); // y pixels/meter
172
+ PutLE32(bmp_header + 46, 0); // number of palette colors
173
+ PutLE32(bmp_header + 50, 0); // important color count
174
+
175
+ // TODO(skal): color profile
176
+
177
+ // write header
178
+ if (fwrite(bmp_header, sizeof(bmp_header), 1, fout) != 1) {
179
+ return 0;
180
+ }
181
+
182
+ // write pixel array
183
+ for (y = 0; y < height; ++y) {
184
+ if (fwrite(rgba + y * stride, line_size, 1, fout) != 1) {
185
+ return 0;
186
+ }
187
+ // write padding zeroes
188
+ if (bmp_stride != line_size) {
189
+ const uint8_t zeroes[3] = { 0 };
190
+ if (fwrite(zeroes, bmp_stride - line_size, 1, fout) != 1) {
191
+ return 0;
192
+ }
193
+ }
194
+ }
195
+ return 1;
196
+ }
197
+ #undef BMP_HEADER_SIZE
@@ -0,0 +1,23 @@
1
+ #include <stdio.h>
2
+ #include <stdlib.h>
3
+
4
+ #include "webp/encode.h"
5
+ #include "webp/decode.h"
6
+
7
+ #ifdef __cplusplus
8
+ extern "C" {
9
+ #endif
10
+
11
+ // Reads a TIFF from 'filename', returning the decoded output in 'pic'.
12
+ // If 'keep_alpha' is true and the TIFF has an alpha channel, the output is RGBA
13
+ // otherwise it will be RGB.
14
+ // Returns true on success.
15
+ int UtilReadTIFF(const char* const filename,
16
+ struct WebPPicture* const pic, int keep_alpha);
17
+
18
+ int UtilWriteTIFF(FILE* fout, const WebPDecBuffer* const buffer);
19
+ int UtilWriteBMP(FILE* fout, const WebPDecBuffer* const buffer);
20
+
21
+ #ifdef __cplusplus
22
+ } // extern "C"
23
+ #endif
@@ -1,15 +1,11 @@
1
- #include "./util.h"
2
- #include <assert.h>
3
1
  #include <stdio.h>
4
2
  #include <stdlib.h>
5
3
  #include <string.h>
6
4
 
7
- #include <png.h>
8
-
9
- #include <setjmp.h> // note: this must be included *after* png.h
10
- #include <jpeglib.h>
11
-
12
- #include <tiffio.h>
5
+ #include "./util.h"
6
+ #include "./jpegdec.h"
7
+ #include "./pngdec.h"
8
+ #include "./tiffdec.h"
13
9
 
14
10
  #include "webp/decode.h"
15
11
  #include "webp/encode.h"
@@ -48,468 +44,6 @@ static int UtilReadYUV(FILE* in_file, WebPPicture* const pic) {
48
44
  return ok;
49
45
  }
50
46
 
51
- struct my_error_mgr {
52
- struct jpeg_error_mgr pub;
53
- jmp_buf setjmp_buffer;
54
- };
55
-
56
- static void my_error_exit(j_common_ptr dinfo) {
57
- struct my_error_mgr* myerr = (struct my_error_mgr*) dinfo->err;
58
- (*dinfo->err->output_message) (dinfo);
59
- longjmp(myerr->setjmp_buffer, 1);
60
- }
61
-
62
- static int UtilReadJPEG(FILE* in_file, WebPPicture* const pic) {
63
- int ok = 0;
64
- int stride, width, height;
65
- uint8_t* rgb = NULL;
66
- struct jpeg_decompress_struct dinfo;
67
- struct my_error_mgr jerr;
68
- JSAMPROW buffer[1];
69
-
70
- dinfo.err = jpeg_std_error(&jerr.pub);
71
- jerr.pub.error_exit = my_error_exit;
72
-
73
- if (setjmp(jerr.setjmp_buffer)) {
74
- Error:
75
- jpeg_destroy_decompress(&dinfo);
76
- goto End;
77
- }
78
-
79
- jpeg_create_decompress(&dinfo);
80
- jpeg_stdio_src(&dinfo, in_file);
81
- jpeg_read_header(&dinfo, TRUE);
82
-
83
- dinfo.out_color_space = JCS_RGB;
84
- dinfo.do_fancy_upsampling = TRUE;
85
-
86
- jpeg_start_decompress(&dinfo);
87
-
88
- if (dinfo.output_components != 3) {
89
- goto Error;
90
- }
91
-
92
- width = dinfo.output_width;
93
- height = dinfo.output_height;
94
- stride = dinfo.output_width * dinfo.output_components * sizeof(*rgb);
95
-
96
- rgb = (uint8_t*)malloc(stride * height);
97
- if (rgb == NULL) {
98
- goto End;
99
- }
100
- buffer[0] = (JSAMPLE*)rgb;
101
-
102
- while (dinfo.output_scanline < dinfo.output_height) {
103
- if (jpeg_read_scanlines(&dinfo, buffer, 1) != 1) {
104
- goto End;
105
- }
106
- buffer[0] += stride;
107
- }
108
-
109
- jpeg_finish_decompress(&dinfo);
110
- jpeg_destroy_decompress(&dinfo);
111
-
112
- // WebP conversion.
113
- pic->width = width;
114
- pic->height = height;
115
- ok = WebPPictureImportRGB(pic, rgb, stride);
116
- if (!ok) goto Error;
117
-
118
- End:
119
- free(rgb);
120
- return ok;
121
- }
122
-
123
- static void PNGAPI error_function(png_structp png, png_const_charp dummy) {
124
- (void)dummy; // remove variable-unused warning
125
- longjmp(png_jmpbuf(png), 1);
126
- }
127
-
128
- static int UtilReadPNG(FILE* in_file, WebPPicture* const pic, int keep_alpha) {
129
- png_structp png;
130
- png_infop info = NULL;
131
- png_infop end_info = NULL;
132
- int color_type, bit_depth, interlaced;
133
- int has_alpha;
134
- int num_passes;
135
- int p;
136
- int ok = 0;
137
- png_uint_32 width, height, y;
138
- int stride;
139
- uint8_t* rgb = NULL;
140
-
141
- png = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
142
- if (png == NULL) {
143
- goto End;
144
- }
145
-
146
- png_set_error_fn(png, 0, error_function, NULL);
147
- if (setjmp(png_jmpbuf(png))) {
148
- Error:
149
- png_destroy_read_struct(&png, &info, &end_info);
150
- goto End;
151
- }
152
-
153
- info = png_create_info_struct(png);
154
- if (info == NULL) goto Error;
155
- end_info = png_create_info_struct(png);
156
- if (end_info == NULL) goto Error;
157
-
158
- png_init_io(png, in_file);
159
- png_read_info(png, info);
160
- if (!png_get_IHDR(png, info,
161
- &width, &height, &bit_depth, &color_type, &interlaced,
162
- NULL, NULL)) goto Error;
163
-
164
- png_set_strip_16(png);
165
- png_set_packing(png);
166
- if (color_type == PNG_COLOR_TYPE_PALETTE) png_set_palette_to_rgb(png);
167
- if (color_type == PNG_COLOR_TYPE_GRAY ||
168
- color_type == PNG_COLOR_TYPE_GRAY_ALPHA) {
169
- if (bit_depth < 8) {
170
- png_set_expand_gray_1_2_4_to_8(png);
171
- }
172
- png_set_gray_to_rgb(png);
173
- }
174
- if (png_get_valid(png, info, PNG_INFO_tRNS)) {
175
- png_set_tRNS_to_alpha(png);
176
- has_alpha = 1;
177
- } else {
178
- has_alpha = !!(color_type & PNG_COLOR_MASK_ALPHA);
179
- }
180
-
181
- if (!keep_alpha) {
182
- png_set_strip_alpha(png);
183
- has_alpha = 0;
184
- }
185
-
186
- num_passes = png_set_interlace_handling(png);
187
- png_read_update_info(png, info);
188
- stride = (has_alpha ? 4 : 3) * width * sizeof(*rgb);
189
- rgb = (uint8_t*)malloc(stride * height);
190
- if (rgb == NULL) goto Error;
191
- for (p = 0; p < num_passes; ++p) {
192
- for (y = 0; y < height; ++y) {
193
- png_bytep row = rgb + y * stride;
194
- png_read_rows(png, &row, NULL, 1);
195
- }
196
- }
197
- png_read_end(png, end_info);
198
- png_destroy_read_struct(&png, &info, &end_info);
199
-
200
- pic->width = width;
201
- pic->height = height;
202
- pic->use_argb = 1;
203
- ok = has_alpha ? WebPPictureImportRGBA(pic, rgb, stride)
204
- : WebPPictureImportRGB(pic, rgb, stride);
205
-
206
- if (!ok) {
207
- goto Error;
208
- }
209
-
210
- End:
211
- free(rgb);
212
- return ok;
213
- }
214
-
215
- static int UtilWritePNG(FILE* out_file, const WebPDecBuffer* const buffer) {
216
- const uint32_t width = buffer->width;
217
- const uint32_t height = buffer->height;
218
- unsigned char* const rgb = buffer->u.RGBA.rgba;
219
- const int stride = buffer->u.RGBA.stride;
220
- const int has_alpha = (buffer->colorspace == MODE_RGBA);
221
- png_structp png;
222
- png_infop info;
223
- png_uint_32 y;
224
-
225
- png = png_create_write_struct(PNG_LIBPNG_VER_STRING,
226
- NULL, error_function, NULL);
227
- if (png == NULL) {
228
- return 0;
229
- }
230
- info = png_create_info_struct(png);
231
- if (info == NULL) {
232
- png_destroy_write_struct(&png, NULL);
233
- return 0;
234
- }
235
- if (setjmp(png_jmpbuf(png))) {
236
- png_destroy_write_struct(&png, &info);
237
- return 0;
238
- }
239
- png_init_io(png, out_file);
240
- png_set_IHDR(png, info, width, height, 8,
241
- has_alpha ? PNG_COLOR_TYPE_RGBA : PNG_COLOR_TYPE_RGB,
242
- PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT,
243
- PNG_FILTER_TYPE_DEFAULT);
244
- png_write_info(png, info);
245
- for (y = 0; y < height; ++y) {
246
- png_bytep row = rgb + y * stride;
247
- png_write_rows(png, &row, 1);
248
- }
249
- png_write_end(png, info);
250
- png_destroy_write_struct(&png, &info);
251
- return 1;
252
- }
253
-
254
- static int UtilWritePPM(FILE* fout, const WebPDecBuffer* const buffer, int alpha) {
255
- const uint32_t width = buffer->width;
256
- const uint32_t height = buffer->height;
257
- const unsigned char* const rgb = buffer->u.RGBA.rgba;
258
- const int stride = buffer->u.RGBA.stride;
259
- const size_t bytes_per_px = alpha ? 4 : 3;
260
- uint32_t y;
261
-
262
- if (alpha) {
263
- fprintf(fout, "P7\nWIDTH %d\nHEIGHT %d\nDEPTH 4\nMAXVAL 255\n"
264
- "TUPLTYPE RGB_ALPHA\nENDHDR\n", width, height);
265
- } else {
266
- fprintf(fout, "P6\n%d %d\n255\n", width, height);
267
- }
268
- for (y = 0; y < height; ++y) {
269
- if (fwrite(rgb + y * stride, width, bytes_per_px, fout) != bytes_per_px) {
270
- return 0;
271
- }
272
- }
273
- return 1;
274
- }
275
-
276
- static void PutLE16(uint8_t* const dst, uint32_t value) {
277
- dst[0] = (value >> 0) & 0xff;
278
- dst[1] = (value >> 8) & 0xff;
279
- }
280
-
281
- static void PutLE32(uint8_t* const dst, uint32_t value) {
282
- PutLE16(dst + 0, (value >> 0) & 0xffff);
283
- PutLE16(dst + 2, (value >> 16) & 0xffff);
284
- }
285
-
286
- #define BMP_HEADER_SIZE 54
287
- static int UtilWriteBMP(FILE* fout, const WebPDecBuffer* const buffer) {
288
- const int has_alpha = (buffer->colorspace != MODE_BGR);
289
- const uint32_t width = buffer->width;
290
- const uint32_t height = buffer->height;
291
- const uint8_t* const rgba = buffer->u.RGBA.rgba;
292
- const int stride = buffer->u.RGBA.stride;
293
- const uint32_t bytes_per_px = has_alpha ? 4 : 3;
294
- uint32_t y;
295
- const uint32_t line_size = bytes_per_px * width;
296
- const uint32_t bmp_stride = (line_size + 3) & ~3; // pad to 4
297
- const uint32_t total_size = bmp_stride * height + BMP_HEADER_SIZE;
298
- uint8_t bmp_header[BMP_HEADER_SIZE] = { 0 };
299
-
300
- // bitmap file header
301
- PutLE16(bmp_header + 0, 0x4d42); // signature 'BM'
302
- PutLE32(bmp_header + 2, total_size); // size including header
303
- PutLE32(bmp_header + 6, 0); // reserved
304
- PutLE32(bmp_header + 10, BMP_HEADER_SIZE); // offset to pixel array
305
- // bitmap info header
306
- PutLE32(bmp_header + 14, 40); // DIB header size
307
- PutLE32(bmp_header + 18, width); // dimensions
308
- PutLE32(bmp_header + 22, -(int)height); // vertical flip!
309
- PutLE16(bmp_header + 26, 1); // number of planes
310
- PutLE16(bmp_header + 28, bytes_per_px * 8); // bits per pixel
311
- PutLE32(bmp_header + 30, 0); // no compression (BI_RGB)
312
- PutLE32(bmp_header + 34, 0); // image size (dummy)
313
- PutLE32(bmp_header + 38, 2400); // x pixels/meter
314
- PutLE32(bmp_header + 42, 2400); // y pixels/meter
315
- PutLE32(bmp_header + 46, 0); // number of palette colors
316
- PutLE32(bmp_header + 50, 0); // important color count
317
-
318
- // TODO(skal): color profile
319
-
320
- // write header
321
- if (fwrite(bmp_header, sizeof(bmp_header), 1, fout) != 1) {
322
- return 0;
323
- }
324
-
325
- // write pixel array
326
- for (y = 0; y < height; ++y) {
327
- if (fwrite(rgba + y * stride, line_size, 1, fout) != 1) {
328
- return 0;
329
- }
330
- // write padding zeroes
331
- if (bmp_stride != line_size) {
332
- const uint8_t zeroes[3] = { 0 };
333
- if (fwrite(zeroes, bmp_stride - line_size, 1, fout) != 1) {
334
- return 0;
335
- }
336
- }
337
- }
338
- return 1;
339
- }
340
- #undef BMP_HEADER_SIZE
341
-
342
- #define NUM_IFD_ENTRIES 15
343
- #define EXTRA_DATA_SIZE 16
344
- // 10b for signature/header + n * 12b entries + 4b for IFD terminator:
345
- #define EXTRA_DATA_OFFSET (10 + 12 * NUM_IFD_ENTRIES + 4)
346
- #define TIFF_HEADER_SIZE (EXTRA_DATA_OFFSET + EXTRA_DATA_SIZE)
347
-
348
- static int UtilWriteTIFF(FILE* fout, const WebPDecBuffer* const buffer) {
349
- const int has_alpha = (buffer->colorspace != MODE_RGB);
350
- const uint32_t width = buffer->width;
351
- const uint32_t height = buffer->height;
352
- const uint8_t* const rgba = buffer->u.RGBA.rgba;
353
- const int stride = buffer->u.RGBA.stride;
354
- const uint8_t bytes_per_px = has_alpha ? 4 : 3;
355
- // For non-alpha case, we omit tag 0x152 (ExtraSamples).
356
- const uint8_t num_ifd_entries = has_alpha ? NUM_IFD_ENTRIES
357
- : NUM_IFD_ENTRIES - 1;
358
- uint8_t tiff_header[TIFF_HEADER_SIZE] = {
359
- 0x49, 0x49, 0x2a, 0x00, // little endian signature
360
- 8, 0, 0, 0, // offset to the unique IFD that follows
361
- // IFD (offset = 8). Entries must be written in increasing tag order.
362
- num_ifd_entries, 0, // Number of entries in the IFD (12 bytes each).
363
- 0x00, 0x01, 3, 0, 1, 0, 0, 0, 0, 0, 0, 0, // 10: Width (TBD)
364
- 0x01, 0x01, 3, 0, 1, 0, 0, 0, 0, 0, 0, 0, // 22: Height (TBD)
365
- 0x02, 0x01, 3, 0, bytes_per_px, 0, 0, 0, // 34: BitsPerSample: 8888
366
- EXTRA_DATA_OFFSET + 0, 0, 0, 0,
367
- 0x03, 0x01, 3, 0, 1, 0, 0, 0, 1, 0, 0, 0, // 46: Compression: none
368
- 0x06, 0x01, 3, 0, 1, 0, 0, 0, 2, 0, 0, 0, // 58: Photometric: RGB
369
- 0x11, 0x01, 4, 0, 1, 0, 0, 0, // 70: Strips offset:
370
- TIFF_HEADER_SIZE, 0, 0, 0, // data follows header
371
- 0x12, 0x01, 3, 0, 1, 0, 0, 0, 1, 0, 0, 0, // 82: Orientation: topleft
372
- 0x15, 0x01, 3, 0, 1, 0, 0, 0, // 94: SamplesPerPixels
373
- bytes_per_px, 0, 0, 0,
374
- 0x16, 0x01, 3, 0, 1, 0, 0, 0, 0, 0, 0, 0, // 106: Rows per strip (TBD)
375
- 0x17, 0x01, 4, 0, 1, 0, 0, 0, 0, 0, 0, 0, // 118: StripByteCount (TBD)
376
- 0x1a, 0x01, 5, 0, 1, 0, 0, 0, // 130: X-resolution
377
- EXTRA_DATA_OFFSET + 8, 0, 0, 0,
378
- 0x1b, 0x01, 5, 0, 1, 0, 0, 0, // 142: Y-resolution
379
- EXTRA_DATA_OFFSET + 8, 0, 0, 0,
380
- 0x1c, 0x01, 3, 0, 1, 0, 0, 0, 1, 0, 0, 0, // 154: PlanarConfiguration
381
- 0x28, 0x01, 3, 0, 1, 0, 0, 0, 2, 0, 0, 0, // 166: ResolutionUnit (inch)
382
- 0x52, 0x01, 3, 0, 1, 0, 0, 0, 1, 0, 0, 0, // 178: ExtraSamples: rgbA
383
- 0, 0, 0, 0, // 190: IFD terminator
384
- // EXTRA_DATA_OFFSET:
385
- 8, 0, 8, 0, 8, 0, 8, 0, // BitsPerSample
386
- 72, 0, 0, 0, 1, 0, 0, 0 // 72 pixels/inch, for X/Y-resolution
387
- };
388
- uint32_t y;
389
-
390
- // Fill placeholders in IFD:
391
- PutLE32(tiff_header + 10 + 8, width);
392
- PutLE32(tiff_header + 22 + 8, height);
393
- PutLE32(tiff_header + 106 + 8, height);
394
- PutLE32(tiff_header + 118 + 8, width * bytes_per_px * height);
395
- if (!has_alpha) PutLE32(tiff_header + 178, 0); // IFD terminator
396
-
397
- // write header
398
- if (fwrite(tiff_header, sizeof(tiff_header), 1, fout) != 1) {
399
- return 0;
400
- }
401
- // write pixel values
402
- for (y = 0; y < height; ++y) {
403
- if (fwrite(rgba + y * stride, bytes_per_px, width, fout) != width) {
404
- return 0;
405
- }
406
- }
407
-
408
- return 1;
409
- }
410
-
411
- #undef TIFF_HEADER_SIZE
412
- #undef EXTRA_DATA_OFFSET
413
- #undef EXTRA_DATA_SIZE
414
- #undef NUM_IFD_ENTRIES
415
-
416
- static int UtilWriteAlphaPlane(FILE* fout, const WebPDecBuffer* const buffer) {
417
- const uint32_t width = buffer->width;
418
- const uint32_t height = buffer->height;
419
- const unsigned char* const a = buffer->u.YUVA.a;
420
- const int a_stride = buffer->u.YUVA.a_stride;
421
- uint32_t y;
422
- assert(a != NULL);
423
- fprintf(fout, "P5\n%d %d\n255\n", width, height);
424
- for (y = 0; y < height; ++y) {
425
- if (fwrite(a + y * a_stride, width, 1, fout) != 1) {
426
- return 0;
427
- }
428
- }
429
- return 1;
430
- }
431
-
432
- static int UtilWritePGM(FILE* fout, const WebPDecBuffer* const buffer) {
433
- const int width = buffer->width;
434
- const int height = buffer->height;
435
- const WebPYUVABuffer* const yuv = &buffer->u.YUVA;
436
- // Save a grayscale PGM file using the IMC4 layout
437
- // (http://www.fourcc.org/yuv.php#IMC4). This is a very
438
- // convenient format for viewing the samples, esp. for
439
- // odd dimensions.
440
- int ok = 1;
441
- int y;
442
- const int uv_width = (width + 1) / 2;
443
- const int uv_height = (height + 1) / 2;
444
- const int out_stride = (width + 1) & ~1;
445
- const int a_height = yuv->a ? height : 0;
446
- fprintf(fout, "P5\n%d %d\n255\n", out_stride, height + uv_height + a_height);
447
- for (y = 0; ok && y < height; ++y) {
448
- ok &= (fwrite(yuv->y + y * yuv->y_stride, width, 1, fout) == 1);
449
- if (width & 1) fputc(0, fout); // padding byte
450
- }
451
- for (y = 0; ok && y < uv_height; ++y) {
452
- ok &= (fwrite(yuv->u + y * yuv->u_stride, uv_width, 1, fout) == 1);
453
- ok &= (fwrite(yuv->v + y * yuv->v_stride, uv_width, 1, fout) == 1);
454
- }
455
- for (y = 0; ok && y < a_height; ++y) {
456
- ok &= (fwrite(yuv->a + y * yuv->a_stride, width, 1, fout) == 1);
457
- if (width & 1) fputc(0, fout); // padding byte
458
- }
459
- return ok;
460
- }
461
-
462
- static int UtilReadTIFF(const char* const filename,
463
- WebPPicture* const pic, int keep_alpha) {
464
- TIFF* const tif = TIFFOpen(filename, "r");
465
- uint32 width, height;
466
- uint32* raster;
467
- int ok = 0;
468
- int dircount = 1;
469
-
470
- if (tif == NULL) {
471
- //fprintf(stderr, "Error! Cannot open TIFF file '%s'\n", filename);
472
- return 0;
473
- }
474
-
475
- while (TIFFReadDirectory(tif)) ++dircount;
476
-
477
- if (dircount > 1) {
478
- fprintf(stderr, "Warning: multi-directory TIFF files are not supported.\n"
479
- "Only the first will be used, %d will be ignored.\n",
480
- dircount - 1);
481
- }
482
-
483
- TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width);
484
- TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height);
485
- raster = (uint32*)_TIFFmalloc(width * height * sizeof(*raster));
486
- if (raster != NULL) {
487
- if (TIFFReadRGBAImageOriented(tif, width, height, raster,
488
- ORIENTATION_TOPLEFT, 1)) {
489
- const int stride = width * sizeof(*raster);
490
- pic->width = width;
491
- pic->height = height;
492
- // TIFF data is ABGR
493
- #ifdef __BIG_ENDIAN__
494
- TIFFSwabArrayOfLong(raster, width * height);
495
- #endif
496
- ok = keep_alpha
497
- ? WebPPictureImportRGBA(pic, (const uint8_t*)raster, stride)
498
- : WebPPictureImportRGBX(pic, (const uint8_t*)raster, stride);
499
- }
500
- _TIFFfree(raster);
501
- } else {
502
- //fprintf(stderr, "Error allocating TIFF RGBA memory!\n");
503
- }
504
-
505
- if (ok && keep_alpha == 2) {
506
- WebPCleanupTransparentArea(pic);
507
- }
508
-
509
- TIFFClose(tif);
510
- return ok;
511
- }
512
-
513
47
  static InputFileFormat GetImageType(FILE* in_file) {
514
48
  InputFileFormat format = UNSUPPORTED;
515
49
  unsigned int magic;
@@ -1,3 +1,3 @@
1
1
  module WebP
2
- VERSION = "0.2.3"
2
+ VERSION = "0.2.4"
3
3
  end
@@ -79,21 +79,21 @@ describe WebP do
79
79
  it "#{image}.png image" do
80
80
  in_filename = File.expand_path(File.join(File.dirname(__FILE__), "factories/#{image}.png"))
81
81
  out_filename = File.expand_path(File.join(@out_dir, "#{image}.png.webp"))
82
- expect(WebP.encode(in_filename, out_filename)).to be_true
82
+ expect(WebP.encode(in_filename, out_filename)).to be_truthy
83
83
  end
84
84
  end
85
85
  factories[:jpg].each do |image|
86
86
  it "#{image}.jpg image" do
87
87
  in_filename = File.expand_path(File.join(File.dirname(__FILE__), "factories/#{image}.jpg"))
88
88
  out_filename = File.expand_path(File.join(@out_dir, "#{image}.jpg.webp"))
89
- expect(WebP.encode(in_filename, out_filename)).to be_true
89
+ expect(WebP.encode(in_filename, out_filename)).to be_truthy
90
90
  end
91
91
  end
92
92
  factories[:tiff].each do |image|
93
93
  it "#{image}.tif image" do
94
94
  in_filename = File.expand_path(File.join(File.dirname(__FILE__), "factories/#{image}.tif"))
95
95
  out_filename = File.expand_path(File.join(@out_dir, "#{image}.tif.webp"))
96
- expect(WebP.encode(in_filename, out_filename)).to be_true
96
+ expect(WebP.encode(in_filename, out_filename)).to be_truthy
97
97
  end
98
98
  end
99
99
  factories[:webp].each do |image|
@@ -128,7 +128,7 @@ describe WebP do
128
128
  it "#{image}.webp image" do
129
129
  in_filename = File.expand_path(File.join(File.dirname(__FILE__), "factories/#{image}.webp"))
130
130
  out_filename = File.expand_path(File.join(@out_dir, "#{image}.webp.png"))
131
- expect(WebP.decode(in_filename, out_filename)).to be_true
131
+ expect(WebP.decode(in_filename, out_filename)).to be_truthy
132
132
  end
133
133
  end
134
134
  context "with output_format" do
@@ -137,7 +137,7 @@ describe WebP do
137
137
  it "#{image}.webp image to #{output_format}" do
138
138
  in_filename = File.expand_path(File.join(File.dirname(__FILE__), "factories/#{image}.webp"))
139
139
  out_filename = File.expand_path(File.join(@out_dir, "#{image}.#{output_format}.png"))
140
- expect(WebP.decode(in_filename, out_filename, output_format: output_format)).to be_true
140
+ expect(WebP.decode(in_filename, out_filename, output_format: output_format)).to be_truthy
141
141
  end
142
142
  end
143
143
  end
@@ -147,12 +147,12 @@ describe WebP do
147
147
  it "#{image}.webp image to png and crop" do
148
148
  in_filename = File.expand_path(File.join(File.dirname(__FILE__), "factories/#{image}.webp"))
149
149
  out_filename = File.expand_path(File.join(@out_dir, "#{image}_crop.png"))
150
- expect(WebP.decode(in_filename, out_filename, crop_w: 200, crop_h: 200)).to be_true
150
+ expect(WebP.decode(in_filename, out_filename, crop_w: 200, crop_h: 200)).to be_truthy
151
151
  end
152
152
  it "#{image}.webp image to png and scale" do
153
153
  in_filename = File.expand_path(File.join(File.dirname(__FILE__), "factories/#{image}.webp"))
154
154
  out_filename = File.expand_path(File.join(@out_dir, "#{image}_resize.png"))
155
- expect(WebP.decode(in_filename, out_filename, resize_w: 200, resize_h: 200)).to be_true
155
+ expect(WebP.decode(in_filename, out_filename, resize_w: 200, resize_h: 200)).to be_truthy
156
156
  end
157
157
  end
158
158
  end
@@ -24,5 +24,5 @@ Gem::Specification.new do |spec|
24
24
 
25
25
  spec.add_development_dependency "bundler", ">= 1.2"
26
26
  spec.add_development_dependency "rake"
27
- spec.add_development_dependency "rspec", ">= 2.14.0"
27
+ spec.add_development_dependency "rspec", ">= 3"
28
28
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: webp-ffi
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.3
4
+ version: 0.2.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alexey Vasyliev
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-05-05 00:00:00.000000000 Z
11
+ date: 2014-07-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ffi
@@ -72,14 +72,14 @@ dependencies:
72
72
  requirements:
73
73
  - - ">="
74
74
  - !ruby/object:Gem::Version
75
- version: 2.14.0
75
+ version: '3'
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - ">="
81
81
  - !ruby/object:Gem::Version
82
- version: 2.14.0
82
+ version: '3'
83
83
  description: Ruby wrapper for libwebp
84
84
  email:
85
85
  - leopard.not.a@gmail.com
@@ -97,6 +97,12 @@ files:
97
97
  - README.md
98
98
  - Rakefile
99
99
  - ext/webp_ffi/Rakefile
100
+ - ext/webp_ffi/jpegdec.c
101
+ - ext/webp_ffi/jpegdec.h
102
+ - ext/webp_ffi/pngdec.c
103
+ - ext/webp_ffi/pngdec.h
104
+ - ext/webp_ffi/tiffdec.c
105
+ - ext/webp_ffi/tiffdec.h
100
106
  - ext/webp_ffi/util.c
101
107
  - ext/webp_ffi/util.h
102
108
  - ext/webp_ffi/webp_ffi.c
@@ -143,7 +149,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
143
149
  version: '0'
144
150
  requirements: []
145
151
  rubyforge_project:
146
- rubygems_version: 2.2.1
152
+ rubygems_version: 2.2.2
147
153
  signing_key:
148
154
  specification_version: 4
149
155
  summary: Ruby wrapper for libwebp