zpng 0.4.4 → 0.4.5
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 +4 -4
- data/VERSION +1 -1
- data/lib/zpng/image.rb +6 -3
- data/lib/zpng/scan_line.rb +38 -5
- data/spec/bad_samples_spec.rb +12 -0
- data/spec/pixel_access_spec.rb +34 -0
- data/zpng.gemspec +3 -3
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 99e5f2ae6f86a27757f442011a5fa365b06f4a4bf52c1348a6018bb0cc8b5f85
|
4
|
+
data.tar.gz: f435672e701c25224d5e61dba082131608567fbe14d86fbd4065495d460d2932
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ce27f95e40b522d1dd854ecb4619650e22a6fc2b5bd4c9aee6c3247e5d32bf98da6778343645723359bb05872e33a68cad9ad08dbc2fae7c0f09c123d6567675
|
7
|
+
data.tar.gz: 3f9ea93a539c4ef1f16900eab6b9e4a8e8f2be7aceed695778cf296dd151df642e1da8b4bff3ff23f34aa560c660816d99d46d462d431547f32455fcfa7375e8
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.4.
|
1
|
+
0.4.5
|
data/lib/zpng/image.rb
CHANGED
@@ -508,11 +508,14 @@ module ZPNG
|
|
508
508
|
end
|
509
509
|
|
510
510
|
def each_pixel &block
|
511
|
-
|
512
|
-
|
513
|
-
|
511
|
+
e = Enumerator.new do |ee|
|
512
|
+
height.times do |y|
|
513
|
+
width.times do |x|
|
514
|
+
ee.yield(self[x,y], x, y)
|
515
|
+
end
|
514
516
|
end
|
515
517
|
end
|
518
|
+
block_given? ? e.each(&block) : e
|
516
519
|
end
|
517
520
|
|
518
521
|
# returns new deinterlaced image if deinterlaced
|
data/lib/zpng/scan_line.rb
CHANGED
@@ -1,4 +1,7 @@
|
|
1
1
|
#coding: binary
|
2
|
+
|
3
|
+
require 'set'
|
4
|
+
|
2
5
|
module ZPNG
|
3
6
|
class ScanLine
|
4
7
|
FILTER_NONE = 0
|
@@ -39,6 +42,7 @@ module ZPNG
|
|
39
42
|
STDERR.puts "[!] #{self.class}: ##@idx: no data at pos 0, scanline dropped".red
|
40
43
|
end
|
41
44
|
end
|
45
|
+
@errors = Set.new
|
42
46
|
end
|
43
47
|
|
44
48
|
# ScanLine is BAD if it has no filter
|
@@ -146,6 +150,24 @@ module ZPNG
|
|
146
150
|
end # case image.hdr.color
|
147
151
|
end
|
148
152
|
|
153
|
+
def get_raw x
|
154
|
+
return nil if @bpp > 8 || image.hdr.color != COLOR_INDEXED
|
155
|
+
|
156
|
+
raw =
|
157
|
+
if @BPP
|
158
|
+
# 8, 16, 24, 32, 48 bits per pixel
|
159
|
+
decoded_bytes[x*@BPP, @BPP]
|
160
|
+
else
|
161
|
+
# 1, 2 or 4 bits per pixel
|
162
|
+
decoded_bytes[x*@bpp/8]
|
163
|
+
end
|
164
|
+
|
165
|
+
mask = 2**@bpp-1
|
166
|
+
shift = 8-(x%(8/@bpp)+1)*@bpp
|
167
|
+
raise "invalid shift #{shift}" if shift < 0 || shift > 7
|
168
|
+
idx = (raw.ord >> shift) & mask
|
169
|
+
end
|
170
|
+
|
149
171
|
def [] x
|
150
172
|
raw =
|
151
173
|
if @BPP
|
@@ -162,6 +184,20 @@ module ZPNG
|
|
162
184
|
shift = 8-(x%(8/@bpp)+1)*@bpp
|
163
185
|
raise "invalid shift #{shift}" if shift < 0 || shift > 7
|
164
186
|
idx = (raw.ord >> shift) & mask
|
187
|
+
color = image.palette[idx]
|
188
|
+
unless color
|
189
|
+
if !@errors.include?(x) && @image.verbose >= -1
|
190
|
+
# prevent same error popping up multiple times, f.ex. in zsteg analysis
|
191
|
+
@errors << x
|
192
|
+
if (32..127).include?(idx)
|
193
|
+
msg = '[!] %s: color #%-3d ("%c") at x=%d y=%d is out of palette!'.red % [self.class, idx, idx, x, @idx]
|
194
|
+
else
|
195
|
+
msg = "[!] %s: color #%-3d at x=%d y=%d is out of palette!".red % [self.class, idx, x, @idx]
|
196
|
+
end
|
197
|
+
STDERR.puts msg
|
198
|
+
end
|
199
|
+
color = Color.new(0,0,0)
|
200
|
+
end
|
165
201
|
if image.trns
|
166
202
|
# transparency from tRNS chunk
|
167
203
|
# For color type 3 (indexed color), the tRNS chunk contains a series of one-byte alpha values,
|
@@ -171,17 +207,14 @@ module ZPNG
|
|
171
207
|
# Alpha for palette index 1: 1 byte
|
172
208
|
# ...
|
173
209
|
#
|
174
|
-
color = image.palette[idx].dup
|
175
210
|
if color.alpha = image.trns.data[idx]
|
176
211
|
# if it's not NULL - convert it from char to int,
|
177
212
|
# otherwise it means fully opaque color, as well as NULL alpha in ZPNG::Color
|
213
|
+
color = color.dup
|
178
214
|
color.alpha = color.alpha.ord
|
179
215
|
end
|
180
|
-
return color
|
181
|
-
else
|
182
|
-
# no transparency
|
183
|
-
return image.palette[idx]
|
184
216
|
end
|
217
|
+
return color
|
185
218
|
|
186
219
|
when COLOR_GRAYSCALE # ALLOWED_DEPTHS: 1, 2, 4, 8, 16
|
187
220
|
c = if @bpp == 16
|
data/spec/bad_samples_spec.rb
CHANGED
@@ -19,6 +19,18 @@ each_sample("bad/*.png") do |fname|
|
|
19
19
|
@img[0,0].should be_instance_of(ZPNG::Color)
|
20
20
|
end
|
21
21
|
|
22
|
+
it "accessess all pixels" do
|
23
|
+
skip "no BPP" unless @img.bpp
|
24
|
+
skip if fname == 'samples/bad/b1.png'
|
25
|
+
skip if fname == 'samples/bad/000000.png'
|
26
|
+
n = 0
|
27
|
+
@img.each_pixel do |px|
|
28
|
+
px.should be_instance_of(ZPNG::Color)
|
29
|
+
n += 1
|
30
|
+
end
|
31
|
+
n.should == @img.width*@img.height
|
32
|
+
end
|
33
|
+
|
22
34
|
describe "CLI" do
|
23
35
|
it "shows info & chunks" do
|
24
36
|
orig_stdout, out = $stdout, ""
|
data/spec/pixel_access_spec.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require File.expand_path(File.join(File.dirname(__FILE__), '/spec_helper'))
|
2
2
|
require 'zpng/cli'
|
3
|
+
require 'set'
|
3
4
|
|
4
5
|
PNGSuite.each_good do |fname|
|
5
6
|
describe fname.sub(%r|\A#{Regexp::escape(Dir.getwd)}/?|, '') do
|
@@ -12,5 +13,38 @@ PNGSuite.each_good do |fname|
|
|
12
13
|
end
|
13
14
|
n.should == img.width*img.height
|
14
15
|
end
|
16
|
+
|
17
|
+
it "accessess all pixels with coords" do
|
18
|
+
img = ZPNG::Image.load(fname)
|
19
|
+
n = 0
|
20
|
+
ax = Set.new
|
21
|
+
ay = Set.new
|
22
|
+
img.each_pixel do |px, x, y|
|
23
|
+
px.should be_instance_of(ZPNG::Color)
|
24
|
+
n += 1
|
25
|
+
ax << x
|
26
|
+
ay << y
|
27
|
+
end
|
28
|
+
n.should == img.width*img.height
|
29
|
+
ax.size.should == img.width
|
30
|
+
ay.size.should == img.height
|
31
|
+
end
|
32
|
+
|
33
|
+
it "accessess all pixels using method #2" do
|
34
|
+
img = ZPNG::Image.load(fname)
|
35
|
+
n = 0
|
36
|
+
a = img.each_pixel.to_a
|
37
|
+
ax = Set.new
|
38
|
+
ay = Set.new
|
39
|
+
a.each do |px, x, y|
|
40
|
+
px.should be_instance_of(ZPNG::Color)
|
41
|
+
n += 1
|
42
|
+
ax << x
|
43
|
+
ay << y
|
44
|
+
end
|
45
|
+
n.should == img.width*img.height
|
46
|
+
ax.size.should == img.width
|
47
|
+
ay.size.should == img.height
|
48
|
+
end
|
15
49
|
end
|
16
50
|
end
|
data/zpng.gemspec
CHANGED
@@ -2,16 +2,16 @@
|
|
2
2
|
# DO NOT EDIT THIS FILE DIRECTLY
|
3
3
|
# Instead, edit Juwelier::Tasks in Rakefile, and run 'rake gemspec'
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
|
-
# stub: zpng 0.4.
|
5
|
+
# stub: zpng 0.4.5 ruby lib
|
6
6
|
|
7
7
|
Gem::Specification.new do |s|
|
8
8
|
s.name = "zpng".freeze
|
9
|
-
s.version = "0.4.
|
9
|
+
s.version = "0.4.5"
|
10
10
|
|
11
11
|
s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
|
12
12
|
s.require_paths = ["lib".freeze]
|
13
13
|
s.authors = ["Andrey \"Zed\" Zaikin".freeze]
|
14
|
-
s.date = "2023-02-
|
14
|
+
s.date = "2023-02-19"
|
15
15
|
s.email = "zed.0xff@gmail.com".freeze
|
16
16
|
s.executables = ["zpng".freeze]
|
17
17
|
s.extra_rdoc_files = [
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: zpng
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrey "Zed" Zaikin
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-02-
|
11
|
+
date: 2023-02-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rainbow
|