webp-ffi 0.2.3 → 0.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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