oily_png 0.0.5 → 0.0.6
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.
- data/.gitignore +2 -1
- data/Gemfile.lock +1 -1
- data/ext/oily_png/extconf.rb +1 -0
- data/ext/oily_png/oily_png_ext.c +1 -3
- data/ext/oily_png/oily_png_ext.h +15 -1
- data/ext/oily_png/png_decoding.c +50 -43
- data/ext/oily_png/png_decoding.h +10 -1
- data/ext/oily_png/png_encoding.c +19 -32
- data/ext/oily_png/png_encoding.h +15 -1
- data/lib/oily_png.rb +1 -1
- data/oily_png.gemspec +3 -4
- data/spec/decoding_spec.rb +6 -0
- data/spec/encoding_spec.rb +10 -2
- data/spec/resources/interlaced.png +0 -0
- metadata +9 -10
data/.gitignore
CHANGED
data/Gemfile.lock
CHANGED
data/ext/oily_png/extconf.rb
CHANGED
data/ext/oily_png/oily_png_ext.c
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
#include "oily_png_ext.h"
|
2
2
|
|
3
|
-
// Initialize the extension by creating the OilyPNG modules.
|
4
3
|
void Init_oily_png_ext() {
|
5
4
|
VALUE OilyPNG = rb_define_module("OilyPNG");
|
6
5
|
|
@@ -13,7 +12,6 @@ void Init_oily_png_ext() {
|
|
13
12
|
rb_define_method(OilyPNG_PNGEncoding, "encode_png_image_pass_to_stream", oily_png_encode_png_image_pass_to_stream, 3);
|
14
13
|
}
|
15
14
|
|
16
|
-
// Returns the number of bytes per pixel for a given color mode.
|
17
15
|
int oily_png_pixel_size(int color_mode) {
|
18
16
|
switch (color_mode) {
|
19
17
|
case OILY_PNG_COLOR_GRAYSCALE: return 1;
|
@@ -21,6 +19,6 @@ int oily_png_pixel_size(int color_mode) {
|
|
21
19
|
case OILY_PNG_COLOR_INDEXED: return 1;
|
22
20
|
case OILY_PNG_COLOR_GRAYSCALE_ALPHA: return 2;
|
23
21
|
case OILY_PNG_COLOR_TRUECOLOR_ALPHA: return 4;
|
24
|
-
default:
|
22
|
+
default: rb_raise(rb_eRuntimeError, "Unsupported color mode: %d", color_mode);
|
25
23
|
}
|
26
24
|
}
|
data/ext/oily_png/oily_png_ext.h
CHANGED
@@ -24,7 +24,21 @@
|
|
24
24
|
#include "png_decoding.h"
|
25
25
|
#include "png_encoding.h"
|
26
26
|
|
27
|
+
|
28
|
+
/*
|
29
|
+
Initialize the extension by creating the OilyPNG modules, and registering
|
30
|
+
the encoding and decoding replacement functions.
|
31
|
+
|
32
|
+
Note, this does not actually replace functionality in ChunkyPNG; you will need
|
33
|
+
to extend the ChunkyPNG::Canvas class with the OilyPNG::PNGDecoding module to
|
34
|
+
speed up decoding, and include OilyPNG::PNGEncoding into the same class to speed
|
35
|
+
up encoding. This is done in lib/oily_png.rb
|
36
|
+
*/
|
27
37
|
void Init_oily_png_ext();
|
38
|
+
|
39
|
+
/*
|
40
|
+
Returns the number of bytes per pixel for a given color mode.
|
41
|
+
*/
|
28
42
|
int oily_png_pixel_size(int color_mode);
|
29
43
|
|
30
|
-
#endif
|
44
|
+
#endif
|
data/ext/oily_png/png_decoding.c
CHANGED
@@ -1,77 +1,73 @@
|
|
1
1
|
#include "oily_png_ext.h"
|
2
2
|
|
3
|
-
////////////////////////////////////////////////////////////////////////////
|
4
|
-
|
5
|
-
// Decodes a pixel at the given position in the bytearray
|
6
|
-
PIXEL oily_png_decode_pixel(int color_mode, BYTE* bytes, int byte_index, VALUE decoding_palette) {
|
7
|
-
switch (color_mode) {
|
8
|
-
case OILY_PNG_COLOR_GRAYSCALE:
|
9
|
-
return (bytes[byte_index] << 24) + (bytes[byte_index] << 16) + (bytes[byte_index] << 8) + 0xff;
|
10
|
-
case OILY_PNG_COLOR_TRUECOLOR:
|
11
|
-
return (bytes[byte_index] << 24) + (bytes[byte_index + 1] << 16) + (bytes[byte_index + 2] << 8) + 0xff;
|
12
|
-
case OILY_PNG_COLOR_INDEXED:
|
13
|
-
return NUM2UINT(rb_funcall(decoding_palette, rb_intern("[]"), 1, INT2FIX(bytes[byte_index])));
|
14
|
-
case OILY_PNG_COLOR_GRAYSCALE_ALPHA:
|
15
|
-
return (bytes[byte_index] << 24) + (bytes[byte_index] << 16) + (bytes[byte_index] << 8) + bytes[byte_index + 1];
|
16
|
-
case OILY_PNG_COLOR_TRUECOLOR_ALPHA:
|
17
|
-
return (bytes[byte_index] << 24) + (bytes[byte_index + 1] << 16) + (bytes[byte_index + 2] << 8) + bytes[byte_index + 3];
|
18
|
-
default:
|
19
|
-
exit(1);
|
20
|
-
}
|
21
|
-
}
|
22
3
|
|
23
4
|
// Decodes a SUB filtered scanline at the given position in the byte array
|
24
5
|
void oily_png_decode_filter_sub(BYTE* bytes, int pos, int line_length, int pixel_size) {
|
25
6
|
int i;
|
26
7
|
for (i = 1 + pixel_size; i < line_length; i++) {
|
27
|
-
bytes[pos + i]
|
8
|
+
UNFILTER_BYTE(bytes[pos + i], bytes[pos + i - pixel_size]);
|
28
9
|
}
|
29
10
|
}
|
30
11
|
|
31
12
|
// Decodes an UP filtered scanline at the given position in the byte array
|
32
|
-
void oily_png_decode_filter_up(BYTE* bytes, int pos, int
|
13
|
+
void oily_png_decode_filter_up(BYTE* bytes, int pos, int line_size, int pixel_size) {
|
33
14
|
int i;
|
34
15
|
// The first line is not filtered because there is no privous line
|
35
|
-
if (pos >=
|
36
|
-
for (i = 1; i <
|
37
|
-
bytes[pos + i]
|
16
|
+
if (pos >= line_size) {
|
17
|
+
for (i = 1; i < line_size; i++) {
|
18
|
+
UNFILTER_BYTE(bytes[pos + i], bytes[pos + i - line_size]);
|
38
19
|
}
|
39
20
|
}
|
40
21
|
}
|
41
22
|
|
42
23
|
// Decodes an AVERAGE filtered scanline at the given position in the byte array
|
43
|
-
void oily_png_decode_filter_average(BYTE* bytes, int pos, int
|
24
|
+
void oily_png_decode_filter_average(BYTE* bytes, int pos, int line_size, int pixel_size) {
|
44
25
|
int i;
|
45
26
|
BYTE a, b;
|
46
|
-
for (i = 1; i <
|
27
|
+
for (i = 1; i < line_size; i++) {
|
47
28
|
a = (i > pixel_size) ? bytes[pos + i - pixel_size] : 0;
|
48
|
-
b = (pos >=
|
49
|
-
bytes[pos + i]
|
29
|
+
b = (pos >= line_size) ? bytes[pos + i - line_size] : 0;
|
30
|
+
UNFILTER_BYTE(bytes[pos + i], (a + b) >> 1);
|
50
31
|
}
|
51
32
|
}
|
52
33
|
|
53
34
|
// Decodes a PAETH filtered scanline at the given position in the byte array
|
54
|
-
void oily_png_decode_filter_paeth(BYTE* bytes, int pos, int
|
35
|
+
void oily_png_decode_filter_paeth(BYTE* bytes, int pos, int line_size, int pixel_size) {
|
55
36
|
BYTE a, b, c, pr;
|
56
37
|
int i, p, pa, pb, pc;
|
57
|
-
for (i = 1; i <
|
38
|
+
for (i = 1; i < line_size; i++) {
|
58
39
|
a = (i > pixel_size) ? bytes[pos + i - pixel_size] : 0;
|
59
|
-
b = (pos >=
|
60
|
-
c = (pos >=
|
40
|
+
b = (pos >= line_size) ? bytes[pos + i - line_size] : 0;
|
41
|
+
c = (pos >= line_size && i > pixel_size) ? bytes[pos + i - line_size - pixel_size] : 0;
|
61
42
|
p = a + b - c;
|
62
43
|
pa = abs(p - a);
|
63
44
|
pb = abs(p - b);
|
64
45
|
pc = abs(p - c);
|
65
46
|
pr = (pa <= pb) ? (pa <= pc ? a : c) : (pb <= pc ? b : c);
|
66
|
-
bytes[pos + i]
|
47
|
+
UNFILTER_BYTE(bytes[pos + i], pr);
|
67
48
|
}
|
68
49
|
}
|
69
50
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
51
|
+
PIXEL oily_png_decode_pixel_grayscale(int color_mode, BYTE* bytes, int byte_index, VALUE decoding_palette) {
|
52
|
+
return BUILD_PIXEL(bytes[byte_index], bytes[byte_index], bytes[byte_index], 0xff);
|
53
|
+
}
|
54
|
+
|
55
|
+
PIXEL oily_png_decode_pixel_truecolor(int color_mode, BYTE* bytes, int byte_index, VALUE decoding_palette) {
|
56
|
+
return BUILD_PIXEL(bytes[byte_index], bytes[byte_index + 1], bytes[byte_index + 2], 0xff);
|
57
|
+
}
|
58
|
+
|
59
|
+
PIXEL oily_png_decode_pixel_indexed(int color_mode, BYTE* bytes, int byte_index, VALUE decoding_palette) {
|
60
|
+
return (PIXEL) NUM2UINT(rb_funcall(decoding_palette, rb_intern("[]"), 1, INT2FIX(bytes[byte_index])));
|
61
|
+
}
|
62
|
+
|
63
|
+
PIXEL oily_png_decode_pixel_grayscale_alpha(int color_mode, BYTE* bytes, int byte_index, VALUE decoding_palette) {
|
64
|
+
return BUILD_PIXEL(bytes[byte_index], bytes[byte_index], bytes[byte_index], bytes[byte_index + 1]);
|
65
|
+
}
|
66
|
+
|
67
|
+
PIXEL oily_png_decode_pixel_truecolor_alpha(int color_mode, BYTE* bytes, int byte_index, VALUE decoding_palette) {
|
68
|
+
return BUILD_PIXEL(bytes[byte_index], bytes[byte_index + 1], bytes[byte_index + 2], bytes[byte_index + 3]);
|
69
|
+
}
|
70
|
+
|
75
71
|
VALUE oily_png_decode_png_image_pass(VALUE self, VALUE stream, VALUE width, VALUE height, VALUE color_mode, VALUE start_pos) {
|
76
72
|
|
77
73
|
int pixel_size = oily_png_pixel_size(FIX2INT(color_mode));
|
@@ -80,8 +76,9 @@ VALUE oily_png_decode_png_image_pass(VALUE self, VALUE stream, VALUE width, VALU
|
|
80
76
|
|
81
77
|
VALUE pixels = rb_ary_new();
|
82
78
|
|
79
|
+
// Make sure that the stream is large enough to contain out pass.
|
83
80
|
if (RSTRING_LEN(stream) < pass_size + FIX2INT(start_pos)) {
|
84
|
-
|
81
|
+
rb_raise(rb_eRuntimeError, "The length of the stream is too short to contain the image!");
|
85
82
|
}
|
86
83
|
|
87
84
|
// Copy the bytes for this pass from the stream to a separate location
|
@@ -96,8 +93,18 @@ VALUE oily_png_decode_png_image_pass(VALUE self, VALUE stream, VALUE width, VALU
|
|
96
93
|
decoding_palette = rb_funcall(self, rb_intern("decoding_palette"), 0);
|
97
94
|
}
|
98
95
|
|
99
|
-
|
100
|
-
BYTE
|
96
|
+
// Select the pixel decoder function for this color mode.
|
97
|
+
PIXEL (*pixel_decoder)(int, BYTE*, int, VALUE);
|
98
|
+
switch (FIX2INT(color_mode)) {
|
99
|
+
case OILY_PNG_COLOR_GRAYSCALE: pixel_decoder = &oily_png_decode_pixel_grayscale; break;
|
100
|
+
case OILY_PNG_COLOR_TRUECOLOR: pixel_decoder = &oily_png_decode_pixel_truecolor; break;
|
101
|
+
case OILY_PNG_COLOR_INDEXED: pixel_decoder = &oily_png_decode_pixel_indexed; break;
|
102
|
+
case OILY_PNG_COLOR_GRAYSCALE_ALPHA: pixel_decoder = &oily_png_decode_pixel_grayscale_alpha; break;
|
103
|
+
case OILY_PNG_COLOR_TRUECOLOR_ALPHA: pixel_decoder = &oily_png_decode_pixel_truecolor_alpha; break;
|
104
|
+
default: rb_raise(rb_eRuntimeError, "Color mode not supported: %d", color_mode);
|
105
|
+
}
|
106
|
+
|
107
|
+
int y, x, line_start, byte_index, pixel_index;
|
101
108
|
PIXEL pixel;
|
102
109
|
|
103
110
|
for (y = 0; y < FIX2INT(height); y++) {
|
@@ -110,7 +117,7 @@ VALUE oily_png_decode_png_image_pass(VALUE self, VALUE stream, VALUE width, VALU
|
|
110
117
|
case OILY_PNG_FILTER_UP: oily_png_decode_filter_up( bytes, line_start, line_size, pixel_size); break;
|
111
118
|
case OILY_PNG_FILTER_AVERAGE: oily_png_decode_filter_average( bytes, line_start, line_size, pixel_size); break;
|
112
119
|
case OILY_PNG_FILTER_PAETH: oily_png_decode_filter_paeth( bytes, line_start, line_size, pixel_size); break;
|
113
|
-
default:
|
120
|
+
default: rb_raise(rb_eRuntimeError, "Filter type not supported: %d", bytes[line_start]);
|
114
121
|
}
|
115
122
|
|
116
123
|
// Set the filter byte to 0 because the bytearray is now unfiltered.
|
@@ -120,7 +127,7 @@ VALUE oily_png_decode_png_image_pass(VALUE self, VALUE stream, VALUE width, VALU
|
|
120
127
|
for (x = 0; x < FIX2INT(width); x++) {
|
121
128
|
pixel_index = FIX2INT(width) * y + x;
|
122
129
|
byte_index = line_start + 1 + (x * pixel_size);
|
123
|
-
pixel =
|
130
|
+
pixel = pixel_decoder(FIX2INT(color_mode), bytes, byte_index, decoding_palette);
|
124
131
|
rb_ary_store(pixels, pixel_index, INT2NUM(pixel));
|
125
132
|
}
|
126
133
|
}
|
data/ext/oily_png/png_decoding.h
CHANGED
@@ -1,7 +1,16 @@
|
|
1
1
|
#ifndef PNG_DECODING_H
|
2
2
|
#define PNG_DECODING_H
|
3
3
|
|
4
|
-
|
4
|
+
#define BUILD_PIXEL(r, g, b, a) (((PIXEL) r << 24) + ((PIXEL) g << 16) + ((PIXEL) b << 8) + (PIXEL) a)
|
5
|
+
#define UNFILTER_BYTE(byte, adjustment) byte = (BYTE) (((byte) + (adjustment)) & 0x000000ff)
|
6
|
+
|
7
|
+
/*
|
8
|
+
Decodes an image pass from the given byte stream at the given position.
|
9
|
+
A normal PNG will only have one pass that consumes the entire stream, while an
|
10
|
+
interlaced image requires 7 passes which are loaded from different starting positions.
|
11
|
+
|
12
|
+
This function shouild replace ChunkyPNG::Canvas::PNGDecoding.decode_png_image_pass
|
13
|
+
*/
|
5
14
|
VALUE oily_png_decode_png_image_pass(VALUE self, VALUE stream, VALUE width, VALUE height, VALUE color_mode, VALUE start_pos);
|
6
15
|
|
7
16
|
#endif
|
data/ext/oily_png/png_encoding.c
CHANGED
@@ -1,42 +1,37 @@
|
|
1
1
|
#include "oily_png_ext.h"
|
2
2
|
|
3
|
-
PIXEL oily_png_encode_get_pixel(VALUE self, long index) {
|
4
|
-
VALUE pixels = rb_funcall(self, rb_intern("pixels"), 0);
|
5
|
-
return NUM2UINT(rb_ary_entry(pixels, index));
|
6
|
-
}
|
7
|
-
|
8
3
|
void oily_png_encode_pixel(PIXEL pixel, int color_mode, BYTE* bytes, int pos, VALUE palette) {
|
9
4
|
switch (color_mode) {
|
10
5
|
case OILY_PNG_COLOR_GRAYSCALE:
|
11
|
-
bytes[pos] = (
|
6
|
+
bytes[pos] = R_BYTE(pixel);
|
12
7
|
break;
|
13
8
|
case OILY_PNG_COLOR_TRUECOLOR:
|
14
|
-
bytes[pos + 0] = (
|
15
|
-
bytes[pos + 1] = (
|
16
|
-
bytes[pos + 2] = (
|
9
|
+
bytes[pos + 0] = R_BYTE(pixel);
|
10
|
+
bytes[pos + 1] = G_BYTE(pixel);
|
11
|
+
bytes[pos + 2] = B_BYTE(pixel);
|
17
12
|
break;
|
18
13
|
case OILY_PNG_COLOR_INDEXED:
|
19
14
|
bytes[pos] = (BYTE) NUM2UINT(rb_funcall(palette, rb_intern("index"), 1, UINT2NUM(pixel)));
|
20
15
|
break;
|
21
16
|
case OILY_PNG_COLOR_GRAYSCALE_ALPHA:
|
22
|
-
bytes[pos + 0] = (
|
23
|
-
bytes[pos + 1] = (
|
17
|
+
bytes[pos + 0] = R_BYTE(pixel);
|
18
|
+
bytes[pos + 1] = A_BYTE(pixel);
|
24
19
|
break;
|
25
20
|
case OILY_PNG_COLOR_TRUECOLOR_ALPHA:
|
26
|
-
bytes[pos + 0] = (
|
27
|
-
bytes[pos + 1] = (
|
28
|
-
bytes[pos + 2] = (
|
29
|
-
bytes[pos + 3] = (
|
21
|
+
bytes[pos + 0] = R_BYTE(pixel);
|
22
|
+
bytes[pos + 1] = G_BYTE(pixel);
|
23
|
+
bytes[pos + 2] = B_BYTE(pixel);
|
24
|
+
bytes[pos + 3] = A_BYTE(pixel);
|
30
25
|
break;
|
31
26
|
default:
|
32
|
-
|
27
|
+
rb_raise(rb_eRuntimeError, "Unsupported color mode: %d", color_mode);
|
33
28
|
}
|
34
29
|
}
|
35
30
|
|
36
31
|
void oily_png_encode_filter_sub(BYTE* bytes, int pos, int line_size, int pixel_size) {
|
37
32
|
int x;
|
38
33
|
for (x = line_size - 1; x > pixel_size; x--) {
|
39
|
-
bytes[pos + x]
|
34
|
+
FILTER_BYTE(bytes[pos + x], bytes[pos + x - pixel_size]);
|
40
35
|
}
|
41
36
|
}
|
42
37
|
|
@@ -44,7 +39,7 @@ void oily_png_encode_filter_up(BYTE* bytes, int pos, int line_size, int pixel_si
|
|
44
39
|
int x;
|
45
40
|
if (pos >= line_size) {
|
46
41
|
for (x = line_size - 1; x > 0; x--) {
|
47
|
-
bytes[pos + x]
|
42
|
+
FILTER_BYTE(bytes[pos + x], bytes[pos + x - line_size]);
|
48
43
|
}
|
49
44
|
}
|
50
45
|
}
|
@@ -54,7 +49,7 @@ void oily_png_encode_filter_average(BYTE* bytes, int pos, int line_size, int pix
|
|
54
49
|
for (x = line_size - 1; x > 0; x--) {
|
55
50
|
a = (x > pixel_size) ? bytes[pos + x - pixel_size] : 0;
|
56
51
|
b = (pos >= line_size) ? bytes[pos + x - line_size] : 0;
|
57
|
-
bytes[pos + x]
|
52
|
+
FILTER_BYTE(bytes[pos + x], (a + b) >> 1);
|
58
53
|
}
|
59
54
|
}
|
60
55
|
|
@@ -69,18 +64,11 @@ void oily_png_encode_filter_paeth(BYTE* bytes, int pos, int line_size, int pixel
|
|
69
64
|
pb = abs(p - b);
|
70
65
|
pc = abs(p - c);
|
71
66
|
pr = (pa <= pb && pa <= pc) ? a : (pb <= pc ? b : c);
|
72
|
-
bytes[pos + x]
|
67
|
+
FILTER_BYTE(bytes[pos + x], pr);
|
73
68
|
}
|
74
69
|
|
75
70
|
}
|
76
71
|
|
77
|
-
|
78
|
-
/*
|
79
|
-
Encodes an image and append it to the stream.
|
80
|
-
A normal PNG will only have one pass and call this method once, while interlaced
|
81
|
-
images are split up in 7 distinct images. This method will be called for every one
|
82
|
-
of these images, reusing the stream.
|
83
|
-
*/
|
84
72
|
VALUE oily_png_encode_png_image_pass_to_stream(VALUE self, VALUE stream, VALUE color_mode, VALUE filtering) {
|
85
73
|
|
86
74
|
// Get the data
|
@@ -89,7 +77,7 @@ VALUE oily_png_encode_png_image_pass_to_stream(VALUE self, VALUE stream, VALUE c
|
|
89
77
|
VALUE pixels = rb_funcall(self, rb_intern("pixels"), 0);
|
90
78
|
|
91
79
|
if (RARRAY_LEN(pixels) != width * height) {
|
92
|
-
|
80
|
+
rb_raise(rb_eRuntimeError, "The number of pixels does not match the canvas dimensions.");
|
93
81
|
}
|
94
82
|
|
95
83
|
VALUE palette = Qnil;
|
@@ -123,12 +111,11 @@ VALUE oily_png_encode_png_image_pass_to_stream(VALUE self, VALUE stream, VALUE c
|
|
123
111
|
case OILY_PNG_FILTER_UP: oily_png_encode_filter_up( bytes, line_size * y, line_size, pixel_size); break;
|
124
112
|
case OILY_PNG_FILTER_AVERAGE: oily_png_encode_filter_average( bytes, line_size * y, line_size, pixel_size); break;
|
125
113
|
case OILY_PNG_FILTER_PAETH: oily_png_encode_filter_paeth( bytes, line_size * y, line_size, pixel_size); break;
|
126
|
-
default:
|
114
|
+
default: rb_raise(rb_eRuntimeError, "Unsupported filter type: %d", FIX2INT(filtering));
|
127
115
|
}
|
128
116
|
}
|
129
117
|
}
|
130
118
|
|
131
|
-
rb_str_cat(stream, bytes, pass_size);
|
132
|
-
|
119
|
+
rb_str_cat(stream, (char*) bytes, pass_size);
|
133
120
|
return Qnil;
|
134
|
-
}
|
121
|
+
}
|
data/ext/oily_png/png_encoding.h
CHANGED
@@ -1,7 +1,21 @@
|
|
1
1
|
#ifndef PNG_ENCODING_H
|
2
2
|
#define PNG_ENCODING_H
|
3
3
|
|
4
|
-
|
4
|
+
#define R_BYTE(pixel) ((BYTE) ((pixel & (PIXEL) 0xff000000) >> 24))
|
5
|
+
#define G_BYTE(pixel) ((BYTE) ((pixel & (PIXEL) 0x00ff0000) >> 16))
|
6
|
+
#define B_BYTE(pixel) ((BYTE) ((pixel & (PIXEL) 0x0000ff00) >> 8))
|
7
|
+
#define A_BYTE(pixel) ((BYTE) ((pixel & (PIXEL) 0x000000ff)))
|
8
|
+
|
9
|
+
#define FILTER_BYTE(byte, adjustment) byte = (BYTE) (((byte) - (adjustment)) & 0x000000ff)
|
10
|
+
|
11
|
+
/*
|
12
|
+
Encodes an image and append it to the stream.
|
13
|
+
A normal PNG will only have one pass and call this method once, while interlaced
|
14
|
+
images are split up in 7 distinct images. This method will be called for every one
|
15
|
+
of these images, reusing the stream.
|
16
|
+
|
17
|
+
This function should replace ChunkyPNG::Canvas::PNGEncoding.encode_png_image_pass_to_stream
|
18
|
+
*/
|
5
19
|
VALUE oily_png_encode_png_image_pass_to_stream(VALUE self, VALUE stream, VALUE color_mode, VALUE filtering);
|
6
20
|
|
7
21
|
#endif
|
data/lib/oily_png.rb
CHANGED
data/oily_png.gemspec
CHANGED
@@ -4,8 +4,8 @@ Gem::Specification.new do |s|
|
|
4
4
|
|
5
5
|
# Do not change the version and date fields by hand. This will be done
|
6
6
|
# automatically by the gem release script.
|
7
|
-
s.version = "0.0.
|
8
|
-
s.date = "2010-10-
|
7
|
+
s.version = "0.0.6"
|
8
|
+
s.date = "2010-10-06"
|
9
9
|
|
10
10
|
s.summary = "Native mixin to speed up ChunkyPNG"
|
11
11
|
s.description = <<-EOT
|
@@ -19,7 +19,6 @@ Gem::Specification.new do |s|
|
|
19
19
|
s.extensions = ["ext/oily_png/extconf.rb"]
|
20
20
|
s.require_paths = ["lib", "ext"]
|
21
21
|
|
22
|
-
s.required_rubygems_version = '1.3.7'
|
23
22
|
s.add_runtime_dependency('chunky_png', '~> 0.10.2')
|
24
23
|
|
25
24
|
s.add_development_dependency('rake')
|
@@ -30,6 +29,6 @@ Gem::Specification.new do |s|
|
|
30
29
|
|
31
30
|
# Do not change the files and test_files fields by hand. This will be done
|
32
31
|
# automatically by the gem release script.
|
33
|
-
s.files = %w(.gitignore Gemfile Gemfile.lock LICENSE README.rdoc Rakefile ext/oily_png/extconf.rb ext/oily_png/oily_png_ext.c ext/oily_png/oily_png_ext.h ext/oily_png/png_decoding.c ext/oily_png/png_decoding.h ext/oily_png/png_encoding.c ext/oily_png/png_encoding.h lib/oily_png.rb oily_png.gemspec spec/decoding_spec.rb spec/encoding_spec.rb spec/resources/gray.png spec/resources/operations.png spec/spec_helper.rb tasks/github-gem.rake)
|
32
|
+
s.files = %w(.gitignore Gemfile Gemfile.lock LICENSE README.rdoc Rakefile ext/oily_png/extconf.rb ext/oily_png/oily_png_ext.c ext/oily_png/oily_png_ext.h ext/oily_png/png_decoding.c ext/oily_png/png_decoding.h ext/oily_png/png_encoding.c ext/oily_png/png_encoding.h lib/oily_png.rb oily_png.gemspec spec/decoding_spec.rb spec/encoding_spec.rb spec/resources/gray.png spec/resources/interlaced.png spec/resources/operations.png spec/spec_helper.rb tasks/github-gem.rake)
|
34
33
|
s.test_files = %w(spec/decoding_spec.rb spec/encoding_spec.rb)
|
35
34
|
end
|
data/spec/decoding_spec.rb
CHANGED
@@ -12,6 +12,12 @@ describe OilyPNG::PNGDecoding do
|
|
12
12
|
OilyCanvas.from_file(resource_file('operations.png'))
|
13
13
|
end
|
14
14
|
|
15
|
+
it "should decode an interlaced image correctly" do
|
16
|
+
c1 = OilyCanvas.from_file(resource_file('interlaced.png'))
|
17
|
+
c2 = ChunkyPNG::Canvas.from_file(resource_file('interlaced.png'))
|
18
|
+
c2.should == c1
|
19
|
+
end
|
20
|
+
|
15
21
|
context 'decoding different filtering methods' do
|
16
22
|
before(:all) { @reference = ChunkyPNG::Canvas.from_file(resource_file('operations.png'))}
|
17
23
|
|
data/spec/encoding_spec.rb
CHANGED
@@ -3,7 +3,7 @@ require 'spec_helper'
|
|
3
3
|
describe OilyPNG::PNGEncoding do
|
4
4
|
|
5
5
|
context 'encoding different color modes' do
|
6
|
-
before do
|
6
|
+
before do
|
7
7
|
@canvas = ChunkyPNG::Canvas.from_file(resource_file('gray.png'))
|
8
8
|
@oily_canvas = OilyCanvas.from_canvas(@canvas)
|
9
9
|
end
|
@@ -78,6 +78,14 @@ describe OilyPNG::PNGEncoding do
|
|
78
78
|
@oily_canvas.send(:encode_png_image_pass_to_stream, stream1 = "", ChunkyPNG::COLOR_TRUECOLOR, ChunkyPNG::FILTER_PAETH)
|
79
79
|
@canvas.send(:encode_png_image_pass_to_stream, stream2 = "", ChunkyPNG::COLOR_TRUECOLOR, ChunkyPNG::FILTER_PAETH)
|
80
80
|
stream1.should == stream2
|
81
|
-
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
it "should encode an interlaced image correctly" do
|
85
|
+
canvas = ChunkyPNG::Canvas.from_file(resource_file('interlaced.png'))
|
86
|
+
data = OilyCanvas.from_canvas(canvas).to_blob(:interlace => true)
|
87
|
+
ds = ChunkyPNG::Datastream.from_blob(data)
|
88
|
+
ds.header_chunk.interlace.should == ChunkyPNG::INTERLACING_ADAM7
|
89
|
+
ChunkyPNG::Canvas.from_datastream(ds).should == canvas
|
82
90
|
end
|
83
91
|
end
|
Binary file
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: oily_png
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 19
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
9
|
+
- 6
|
10
|
+
version: 0.0.6
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Willem van Bergen
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-10-
|
18
|
+
date: 2010-10-06 00:00:00 +02:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -91,6 +91,7 @@ files:
|
|
91
91
|
- spec/decoding_spec.rb
|
92
92
|
- spec/encoding_spec.rb
|
93
93
|
- spec/resources/gray.png
|
94
|
+
- spec/resources/interlaced.png
|
94
95
|
- spec/resources/operations.png
|
95
96
|
- spec/spec_helper.rb
|
96
97
|
- tasks/github-gem.rake
|
@@ -121,14 +122,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
121
122
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
122
123
|
none: false
|
123
124
|
requirements:
|
124
|
-
- - "
|
125
|
+
- - ">="
|
125
126
|
- !ruby/object:Gem::Version
|
126
|
-
hash:
|
127
|
+
hash: 3
|
127
128
|
segments:
|
128
|
-
-
|
129
|
-
|
130
|
-
- 7
|
131
|
-
version: 1.3.7
|
129
|
+
- 0
|
130
|
+
version: "0"
|
132
131
|
requirements: []
|
133
132
|
|
134
133
|
rubyforge_project: oily_png
|