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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6b35d6d1f87f6a32f1de261d07be9a5670cad8892fdf8033a46c6189ac60c6c5
4
- data.tar.gz: 584811c71db552f0b07f701f324b3e359d101c7650c975280f6c529cc8ecb246
3
+ metadata.gz: 99e5f2ae6f86a27757f442011a5fa365b06f4a4bf52c1348a6018bb0cc8b5f85
4
+ data.tar.gz: f435672e701c25224d5e61dba082131608567fbe14d86fbd4065495d460d2932
5
5
  SHA512:
6
- metadata.gz: e22d560929ca762532c078ac6ab7732788032ec58e86d20156c35169f0ebf44c498b69069adcb563b70ab8f770aa20116c5c5da4e9bd2847a716c504bc164c5f
7
- data.tar.gz: b34d79aa9ca9b1c4bfa8770ca59c463eff6155687e27891f143b19fc142e07c914e1d7412f51446bacb6ba637b3879c9e662c06cb0003b51fff4d102b2ec5d8c
6
+ metadata.gz: ce27f95e40b522d1dd854ecb4619650e22a6fc2b5bd4c9aee6c3247e5d32bf98da6778343645723359bb05872e33a68cad9ad08dbc2fae7c0f09c123d6567675
7
+ data.tar.gz: 3f9ea93a539c4ef1f16900eab6b9e4a8e8f2be7aceed695778cf296dd151df642e1da8b4bff3ff23f34aa560c660816d99d46d462d431547f32455fcfa7375e8
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.4.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
- height.times do |y|
512
- width.times do |x|
513
- yield(self[x,y], x, y)
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
@@ -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
@@ -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, ""
@@ -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.4 ruby lib
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.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"
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
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-14 00:00:00.000000000 Z
11
+ date: 2023-02-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rainbow