zpng 0.1.0 → 0.1.1

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/Gemfile CHANGED
@@ -2,8 +2,8 @@ source "http://rubygems.org"
2
2
  # Add dependencies required to use your gem here.
3
3
  # Example:
4
4
  # gem "activesupport", ">= 2.3.5"
5
- gem 'colorize'
6
5
  gem 'hexdump'
6
+ gem 'rainbow'
7
7
 
8
8
  # Add dependencies to develop your gem here.
9
9
  # Include everything needed to run rake, tests, features, etc.
data/Gemfile.lock CHANGED
@@ -1,7 +1,6 @@
1
1
  GEM
2
2
  remote: http://rubygems.org/
3
3
  specs:
4
- colorize (0.5.8)
5
4
  diff-lcs (1.1.3)
6
5
  git (1.2.5)
7
6
  hexdump (0.2.3)
@@ -11,6 +10,7 @@ GEM
11
10
  rake
12
11
  rdoc
13
12
  json (1.7.5)
13
+ rainbow (1.1.4)
14
14
  rake (10.0.2)
15
15
  rdoc (3.12)
16
16
  json (~> 1.4)
@@ -28,7 +28,7 @@ PLATFORMS
28
28
 
29
29
  DEPENDENCIES
30
30
  bundler (>= 1.0.0)
31
- colorize
32
31
  hexdump
33
32
  jeweler (~> 1.8.4)
33
+ rainbow
34
34
  rspec (>= 2.8.0)
data/README.md CHANGED
@@ -20,13 +20,18 @@ Usage
20
20
  -q, --quiet Silent any warnings (can be used multiple times)
21
21
  -C, --chunks Show file chunks (default)
22
22
  -i, --info General image info (default)
23
- -A, --ascii Try to display image as ASCII (works best with monochrome images)
24
23
  -S, --scanlines Show scanlines info
25
24
  -P, --palette Show palette
26
25
  -E, --extract-chunk ID extract a single chunk
27
26
  -U, --unpack-imagedata unpack Image Data (IDAT) chunk(s), output to stdout
27
+
28
28
  -c, --crop GEOMETRY crop image, {WIDTH}x{HEIGHT}+{X}+{Y},
29
29
  puts results on stdout unless --ascii given
30
+
31
+ -A, --ascii Try to convert image to ASCII (works best with monochrome images)
32
+ -N, --ansi Try to display image as ANSI colored text
33
+ -2, --256 Try to display image as 256-colored text
34
+ -W, --wide Use 2 horizontal characters per one pixel
30
35
 
31
36
  ### Info
32
37
 
@@ -39,7 +44,7 @@ Usage
39
44
 
40
45
  # zpng --chunks qr_aux_chunks.png
41
46
 
42
- [.] <Chunk #00 IHDR size= 13, crc=36a28ef4, width=35, height=35, depth=1, color=0, compression=0, filter=0, interlace=0, idx=0> CRC OK
47
+ [.] <Chunk #00 IHDR size= 13, crc=36a28ef4, idx=0, interlace=0, filter=0, compression=0, height=35, width=35, depth=1, color=0> CRC OK
43
48
  [.] <Chunk #01 gAMA size= 4, crc=0bfc6105 > CRC OK
44
49
  [.] <Chunk #02 sRGB size= 1, crc=aece1ce9 > CRC OK
45
50
  [.] <Chunk #03 cHRM size= 32, crc=9cba513c > CRC OK
@@ -53,82 +58,82 @@ Usage
53
58
 
54
59
  source image: ![qr_rgb.png](https://github.com/zed-0xff/zpng/raw/master/samples/qr_rgb.png)
55
60
 
56
- # zpng --ascii qr_rgb.png
57
-
58
-
59
- ####### ## ## # ## #######
60
- # # ## # ## # #
61
- # ### # # ##### # # ## # ### #
62
- # ### # ## # # #### ## # ### #
63
- # ### # #### # # #### # ### #
64
- # # # # # ##### # #
65
- ####### # # # # # # # # # #######
66
- # # ## ## ##
67
- #### # # ## # ## ## ### #
68
- # ## ## ## # ## # ### ##
69
- # ### ## ## # ## ## # ### #
70
- ### # ##### # # ## # #
71
- ## ## # # # # #### ## ##
72
- # # ## ## # # ### ## ##
73
- # ###### ## # # ##### #######
74
- # #### ### ## # ## # ## #
75
- ## ## ### ## # ## ########
76
- # ### ## ## ######### #
77
- #### ##### ## ## # # # #
78
- ## # # # # ##### # # ## #
79
- ###### ##### # # ## #
80
- ### # #### # ### # ###
81
- ### #### #### # # ####### ##
82
- # # ## ## # ## # ## ###### #
83
- # ####### # ## ## ##### #
84
- # ### # ## ## # #
85
- ####### # # ## ### # #
86
- # # ### # # ###### ### #
87
- # ### # # #### # ########
88
- # ### # ### # #### # # #
89
- # ### # ### ##### # ## # #
90
- # # #### ## ## ### #
91
- ####### # # ## # ## # ## #
61
+ # zpng --ascii --wide qr_rgb.png
62
+
63
+
64
+ ############## #### #### ## #### ##############
65
+ ## ## #### ## #### ## ##
66
+ ## ###### ## ## ########## ## ## #### ## ###### ##
67
+ ## ###### ## #### ## ## ######## #### ## ###### ##
68
+ ## ###### ## ######## ## ## ######## ## ###### ##
69
+ ## ## ## ## ## ########## ## ##
70
+ ############## ## ## ## ## ## ## ## ## ## ##############
71
+ ## ## #### #### ####
72
+ ######## ## ## #### ## #### #### ###### ##
73
+ ## #### #### #### ## #### ## ###### ####
74
+ ## ###### #### #### ## #### #### ## ###### ##
75
+ ###### ## ########## ## ## #### ## ##
76
+ #### #### ## ## ## ## ######## #### ####
77
+ ## ## #### #### ## ## ###### #### ####
78
+ ## ############ #### ## ## ########## ##############
79
+ ## ######## ###### #### ## #### ## #### ##
80
+ #### #### ###### #### ## #### ################
81
+ ## ###### #### #### ################## ##
82
+ ######## ########## #### #### ## ## ## ##
83
+ #### ## ## ## ## ########## ## ## #### ##
84
+ ############ ########## ## ## #### ##
85
+ ###### ## ######## ## ###### ## ######
86
+ ###### ######## ######## ## ## ############## ####
87
+ ## ## #### #### ## #### ## #### ############ ##
88
+ ## ############## ## #### #### ########## ##
89
+ ## ###### ## #### #### ## ##
90
+ ############## ## ## #### ###### ## ##
91
+ ## ## ###### ## ## ############ ###### ##
92
+ ## ###### ## ## ######## ## ################
93
+ ## ###### ## ###### ## ######## ## ## ##
94
+ ## ###### ## ###### ########## ## #### ## ##
95
+ ## ## ######## #### #### ###### ##
96
+ ############## ## ## #### ## #### ## #### ##
92
97
 
93
98
  ### Scanlines
94
99
 
95
100
  # zpng --scanlines qr_rgb.png
96
101
 
97
- [#<ZPNG::ScanLine idx=0, bpp=24, offset=1, filter=1>,
98
- #<ZPNG::ScanLine idx=1, bpp=24, offset=107, filter=4>,
99
- #<ZPNG::ScanLine idx=2, bpp=24, offset=213, filter=4>,
100
- #<ZPNG::ScanLine idx=3, bpp=24, offset=319, filter=4>,
101
- #<ZPNG::ScanLine idx=4, bpp=24, offset=425, filter=2>,
102
- #<ZPNG::ScanLine idx=5, bpp=24, offset=531, filter=2>,
103
- #<ZPNG::ScanLine idx=6, bpp=24, offset=637, filter=4>,
104
- #<ZPNG::ScanLine idx=7, bpp=24, offset=743, filter=0>,
105
- #<ZPNG::ScanLine idx=8, bpp=24, offset=849, filter=1>,
106
- #<ZPNG::ScanLine idx=9, bpp=24, offset=955, filter=0>,
107
- #<ZPNG::ScanLine idx=10, bpp=24, offset=1061, filter=0>,
108
- #<ZPNG::ScanLine idx=11, bpp=24, offset=1167, filter=0>,
109
- #<ZPNG::ScanLine idx=12, bpp=24, offset=1273, filter=1>,
110
- #<ZPNG::ScanLine idx=13, bpp=24, offset=1379, filter=2>,
111
- #<ZPNG::ScanLine idx=14, bpp=24, offset=1485, filter=4>,
112
- #<ZPNG::ScanLine idx=15, bpp=24, offset=1591, filter=0>,
113
- #<ZPNG::ScanLine idx=16, bpp=24, offset=1697, filter=4>,
114
- #<ZPNG::ScanLine idx=17, bpp=24, offset=1803, filter=0>,
115
- #<ZPNG::ScanLine idx=18, bpp=24, offset=1909, filter=4>,
116
- #<ZPNG::ScanLine idx=19, bpp=24, offset=2015, filter=4>,
117
- #<ZPNG::ScanLine idx=20, bpp=24, offset=2121, filter=0>,
118
- #<ZPNG::ScanLine idx=21, bpp=24, offset=2227, filter=1>,
119
- #<ZPNG::ScanLine idx=22, bpp=24, offset=2333, filter=2>,
120
- #<ZPNG::ScanLine idx=23, bpp=24, offset=2439, filter=0>,
121
- #<ZPNG::ScanLine idx=24, bpp=24, offset=2545, filter=2>,
122
- #<ZPNG::ScanLine idx=25, bpp=24, offset=2651, filter=1>,
123
- #<ZPNG::ScanLine idx=26, bpp=24, offset=2757, filter=1>,
124
- #<ZPNG::ScanLine idx=27, bpp=24, offset=2863, filter=4>,
125
- #<ZPNG::ScanLine idx=28, bpp=24, offset=2969, filter=4>,
126
- #<ZPNG::ScanLine idx=29, bpp=24, offset=3075, filter=4>,
127
- #<ZPNG::ScanLine idx=30, bpp=24, offset=3181, filter=4>,
128
- #<ZPNG::ScanLine idx=31, bpp=24, offset=3287, filter=2>,
129
- #<ZPNG::ScanLine idx=32, bpp=24, offset=3393, filter=4>,
130
- #<ZPNG::ScanLine idx=33, bpp=24, offset=3499, filter=4>,
131
- #<ZPNG::ScanLine idx=34, bpp=24, offset=3605, filter=1>]
102
+ [#<ZPNG::ScanLine idx=0 offset=1 size=106 bpp=24 filter=1>,
103
+ #<ZPNG::ScanLine idx=1 offset=107 size=106 bpp=24 filter=4>,
104
+ #<ZPNG::ScanLine idx=2 offset=213 size=106 bpp=24 filter=4>,
105
+ #<ZPNG::ScanLine idx=3 offset=319 size=106 bpp=24 filter=4>,
106
+ #<ZPNG::ScanLine idx=4 offset=425 size=106 bpp=24 filter=2>,
107
+ #<ZPNG::ScanLine idx=5 offset=531 size=106 bpp=24 filter=2>,
108
+ #<ZPNG::ScanLine idx=6 offset=637 size=106 bpp=24 filter=4>,
109
+ #<ZPNG::ScanLine idx=7 offset=743 size=106 bpp=24 filter=0>,
110
+ #<ZPNG::ScanLine idx=8 offset=849 size=106 bpp=24 filter=1>,
111
+ #<ZPNG::ScanLine idx=9 offset=955 size=106 bpp=24 filter=0>,
112
+ #<ZPNG::ScanLine idx=10 offset=1061 size=106 bpp=24 filter=0>,
113
+ #<ZPNG::ScanLine idx=11 offset=1167 size=106 bpp=24 filter=0>,
114
+ #<ZPNG::ScanLine idx=12 offset=1273 size=106 bpp=24 filter=1>,
115
+ #<ZPNG::ScanLine idx=13 offset=1379 size=106 bpp=24 filter=2>,
116
+ #<ZPNG::ScanLine idx=14 offset=1485 size=106 bpp=24 filter=4>,
117
+ #<ZPNG::ScanLine idx=15 offset=1591 size=106 bpp=24 filter=0>,
118
+ #<ZPNG::ScanLine idx=16 offset=1697 size=106 bpp=24 filter=4>,
119
+ #<ZPNG::ScanLine idx=17 offset=1803 size=106 bpp=24 filter=0>,
120
+ #<ZPNG::ScanLine idx=18 offset=1909 size=106 bpp=24 filter=4>,
121
+ #<ZPNG::ScanLine idx=19 offset=2015 size=106 bpp=24 filter=4>,
122
+ #<ZPNG::ScanLine idx=20 offset=2121 size=106 bpp=24 filter=0>,
123
+ #<ZPNG::ScanLine idx=21 offset=2227 size=106 bpp=24 filter=1>,
124
+ #<ZPNG::ScanLine idx=22 offset=2333 size=106 bpp=24 filter=2>,
125
+ #<ZPNG::ScanLine idx=23 offset=2439 size=106 bpp=24 filter=0>,
126
+ #<ZPNG::ScanLine idx=24 offset=2545 size=106 bpp=24 filter=2>,
127
+ #<ZPNG::ScanLine idx=25 offset=2651 size=106 bpp=24 filter=1>,
128
+ #<ZPNG::ScanLine idx=26 offset=2757 size=106 bpp=24 filter=1>,
129
+ #<ZPNG::ScanLine idx=27 offset=2863 size=106 bpp=24 filter=4>,
130
+ #<ZPNG::ScanLine idx=28 offset=2969 size=106 bpp=24 filter=4>,
131
+ #<ZPNG::ScanLine idx=29 offset=3075 size=106 bpp=24 filter=4>,
132
+ #<ZPNG::ScanLine idx=30 offset=3181 size=106 bpp=24 filter=4>,
133
+ #<ZPNG::ScanLine idx=31 offset=3287 size=106 bpp=24 filter=2>,
134
+ #<ZPNG::ScanLine idx=32 offset=3393 size=106 bpp=24 filter=4>,
135
+ #<ZPNG::ScanLine idx=33 offset=3499 size=106 bpp=24 filter=4>,
136
+ #<ZPNG::ScanLine idx=34 offset=3605 size=106 bpp=24 filter=1>]
132
137
 
133
138
  ### Palette
134
139
 
data/README.md.tpl CHANGED
@@ -27,7 +27,7 @@ Usage
27
27
 
28
28
  source image: ![qr_rgb.png](https://github.com/zed-0xff/zpng/raw/master/samples/qr_rgb.png)
29
29
 
30
- % zpng --ascii qr_rgb.png
30
+ % zpng --ascii --wide qr_rgb.png
31
31
 
32
32
  ### Scanlines
33
33
 
data/Rakefile CHANGED
@@ -86,8 +86,7 @@ Rake::Task[:console].clear
86
86
  # from /usr/local/lib64/ruby/gems/1.9.1/gems/jeweler-1.8.4/lib/jeweler/tasks.rb
87
87
  desc "Start IRB with all runtime dependencies loaded"
88
88
  task :console, [:script] do |t,args|
89
- # TODO move to a command
90
- dirs = ['ext', 'lib'].select { |dir| File.directory?(dir) }
89
+ dirs = ['./ext', './lib'].select { |dir| File.directory?(dir) }
91
90
 
92
91
  original_load_path = $LOAD_PATH
93
92
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.0
1
+ 0.1.1
@@ -0,0 +1,63 @@
1
+ module ZPNG
2
+ class Adam7Decoder
3
+ attr_accessor :image
4
+
5
+ def initialize image
6
+ @image = image
7
+ end
8
+
9
+ def scanlines_count
10
+ (15*image.height/8.0).ceil
11
+ end
12
+
13
+ WIDTHS = [1,1,2,2,2,4,4,4,4,4,4,8,8,8,8]
14
+
15
+ # scanline width in pixels
16
+ def scanline_width idx
17
+ #image.width/8*(2**(idx/2))
18
+ WIDTHS[idx*8/image.height]*(image.width/8)
19
+ end
20
+
21
+ # scanline size in bytes, INCLUDING leading filter byte
22
+ def scanline_size idx
23
+ (scanline_width(idx) * image.bpp / 8.0).ceil + 1
24
+ end
25
+
26
+ # scanline offset in imagedata
27
+ def scanline_offset idx
28
+ #TODO: optimize
29
+ (0...idx).map{ |x| scanline_size(x) }.inject(&:+) || 0
30
+ end
31
+
32
+ # convert "flat" coords in scanline number & pos in scanline
33
+ def convert_coords x,y
34
+ # optimizing this into one switch/case statement gives
35
+ # about 1-2% speed increase (ruby 1.9.3p286)
36
+
37
+ if y%2 == 1
38
+ # 7th pass: last height/2 full scanlines
39
+ [x, y/2 + image.height*11/8]
40
+ elsif x%2 == 1 && y%2 == 0
41
+ # 6th pass
42
+ [x/2, y/2 + image.height*7/8]
43
+ elsif x%8 == 0 && y%8 == 0
44
+ # 1st pass
45
+ [x/8, y/8]
46
+ elsif x%8 == 4 && y%8 == 0
47
+ # 2nd pass
48
+ [x/8, y/8 + image.height/8]
49
+ elsif x%4 == 0 && y%8 == 4
50
+ # 3rd pass
51
+ [x/4, y/8 + image.height*2/8]
52
+ elsif x%4 == 2 && y%4 == 0
53
+ # 4th pass
54
+ [x/4, y/4 + image.height*3/8]
55
+ elsif x%2 == 0 && y%4 == 2
56
+ # 5th pass
57
+ [x/2, y/4 + image.height*5/8]
58
+ else
59
+ raise "invalid coords"
60
+ end
61
+ end
62
+ end
63
+ end
data/lib/zpng/cli.rb CHANGED
@@ -8,7 +8,6 @@ class ZPNG::CLI
8
8
  ACTIONS = {
9
9
  'chunks' => 'Show file chunks (default)',
10
10
  %w'i info' => 'General image info (default)',
11
- 'ascii' => 'Try to display image as ASCII (works best with monochrome images)',
12
11
  'scanlines' => 'Show scanlines info',
13
12
  'palette' => 'Show palette'
14
13
  }
@@ -46,10 +45,25 @@ class ZPNG::CLI
46
45
  @actions << :unpack_imagedata
47
46
  end
48
47
 
48
+ opts.separator ""
49
49
  opts.on "-c", "--crop GEOMETRY", "crop image, {WIDTH}x{HEIGHT}+{X}+{Y},",
50
50
  "puts results on stdout unless --ascii given" do |x|
51
51
  @actions << [:crop, x]
52
52
  end
53
+
54
+ opts.separator ""
55
+ opts.on "-A", '--ascii', 'Try to convert image to ASCII (works best with monochrome images)' do
56
+ @actions << :ascii
57
+ end
58
+ opts.on "-N", '--ansi', 'Try to display image as ANSI colored text' do
59
+ @actions << :ansi
60
+ end
61
+ opts.on "-2", '--256', 'Try to display image as 256-colored text' do
62
+ @actions << :ansi256
63
+ end
64
+ opts.on "-W", '--wide', 'Use 2 horizontal characters per one pixel' do
65
+ @options[:wide] = true
66
+ end
53
67
  end
54
68
 
55
69
  if (argv = optparser.parse(@argv)).empty?
@@ -120,7 +134,35 @@ class ZPNG::CLI
120
134
  end
121
135
 
122
136
  def ascii
123
- puts @img.to_s
137
+ @img.height.times do |y|
138
+ @img.width.times do |x|
139
+ c = @img[x,y].to_ascii
140
+ c *= 2 if @options[:wide]
141
+ print c
142
+ end
143
+ puts
144
+ end
145
+ end
146
+
147
+ def ansi
148
+ spc = @options[:wide] ? " " : " "
149
+ @img.height.times do |y|
150
+ @img.width.times do |x|
151
+ print spc.background(@img[x,y].closest_ansi_color)
152
+ end
153
+ puts
154
+ end
155
+ end
156
+
157
+ def ansi256
158
+ require 'rainbow'
159
+ spc = @options[:wide] ? " " : " "
160
+ @img.height.times do |y|
161
+ @img.width.times do |x|
162
+ print spc.background(@img[x,y].to_s)
163
+ end
164
+ puts
165
+ end
124
166
  end
125
167
 
126
168
  def scanlines
data/lib/zpng/color.rb CHANGED
@@ -9,8 +9,33 @@ module ZPNG
9
9
  alias :alpha :a
10
10
  def alpha= v; self.a = v; end
11
11
 
12
- BLACK = Color.new(0,0,0,0xff)
13
- WHITE = Color.new(0xff,0xff,0xff,0xff)
12
+ BLACK = Color.new(0 , 0, 0, 255)
13
+ WHITE = Color.new(255,255,255, 255)
14
+
15
+ RED = Color.new(255, 0, 0, 255)
16
+ GREEN = Color.new(0 ,255, 0, 255)
17
+ BLUE = Color.new(0 , 0,255, 255)
18
+
19
+ YELLOW= Color.new(255,255, 0, 255)
20
+ CYAN = Color.new( 0,255,255, 255)
21
+ PURPLE= MAGENTA =
22
+ Color.new(255, 0,255, 255)
23
+
24
+ ANSI_COLORS = [:black, :red, :green, :yellow, :blue, :magenta, :cyan, :white]
25
+
26
+ # euclidian distance - http://en.wikipedia.org/wiki/Euclidean_distance
27
+ def euclidian other_color
28
+ r = (self.r.to_i - other_color.r.to_i)**2
29
+ r += (self.g.to_i - other_color.g.to_i)**2
30
+ r += (self.b.to_i - other_color.b.to_i)**2
31
+ Math.sqrt r
32
+ end
33
+
34
+ def closest_ansi_color
35
+ a = ANSI_COLORS.map{|c| self.class.const_get(c.to_s.upcase) }
36
+ a.map!{ |c| self.euclidian(c) }
37
+ ANSI_COLORS[a.index(a.min)]
38
+ end
14
39
 
15
40
  def white?
16
41
  r == 0xff && g == 0xff && b == 0xff
@@ -36,6 +61,15 @@ module ZPNG
36
61
  "%02X%02X%02X" % [r,g,b]
37
62
  end
38
63
 
64
+ # try to convert to pseudographics
65
+ def to_ascii h={}
66
+ white = h[:white] || ' '
67
+ black = h[:black] || '#'
68
+ unknown = h[:unknown] || '?'
69
+
70
+ self.white?? white : (self.black?? black : unknown)
71
+ end
72
+
39
73
  def to_i
40
74
  ((a||0) << 24) + ((r||0) << 16) + ((g||0) << 8) + (b||0)
41
75
  end
@@ -47,8 +81,13 @@ module ZPNG
47
81
  rs = r ? "%02x" % r : "??"
48
82
  gs = g ? "%02x" % g : "??"
49
83
  bs = b ? "%02x" % b : "??"
50
- as = a ? "%d" % a : "?"
51
- "#<ZPNG::Color #%s%s%s%s a=%s>" % [rs,gs,bs,as]
84
+ if a
85
+ # alpha is non-NULL
86
+ "#<ZPNG::Color #%s%s%s a=%d>" % [rs,gs,bs,a]
87
+ else
88
+ # alpha is NULL
89
+ "#<ZPNG::Color #%s%s%s>" % [rs,gs,bs]
90
+ end
52
91
  end
53
92
  end
54
93
  end
data/lib/zpng/image.rb CHANGED
@@ -22,6 +22,10 @@ module ZPNG
22
22
  end
23
23
  end
24
24
 
25
+ def adam7
26
+ @adam7 ||= Adam7Decoder.new(self)
27
+ end
28
+
25
29
  # load image from file
26
30
  def self.load fname
27
31
  open(fname,"rb") do |f|
@@ -49,7 +53,7 @@ module ZPNG
49
53
  @chunks << (@header = Chunk::IHDR.new(h))
50
54
  if @header.palette_used?
51
55
  @chunks << (@palette = Chunk::PLTE.new)
52
- @palette[0] = h[:bg] || Color::BLACK # add default bg color
56
+ @palette[0] = h[:background] || h[:bg] || Color::BLACK # add default bg color
53
57
  end
54
58
  end
55
59
 
@@ -98,6 +102,10 @@ module ZPNG
98
102
  end
99
103
  end
100
104
 
105
+ def bpp
106
+ @header && @header.bpp
107
+ end
108
+
101
109
  def width
102
110
  @header && @header.width
103
111
  end
@@ -110,25 +118,27 @@ module ZPNG
110
118
  @header && @header.grayscale?
111
119
  end
112
120
 
121
+ def interlaced?
122
+ @header && @header.interlace != 0
123
+ end
124
+
113
125
  def imagedata
114
126
  @imagedata ||=
115
127
  begin
116
- if @header
117
- raise "only non-interlaced mode is supported for imagedata" if @header.interlace != 0
118
- else
119
- puts "[?] no image header, assuming non-interlaced RGB".yellow
120
- end
128
+ puts "[?] no image header, assuming non-interlaced RGB".yellow unless @header
121
129
  data = @chunks.find_all{ |c| c.is_a?(Chunk::IDAT) }.map(&:data).join
122
130
  (data && data.size > 0) ? Zlib::Inflate.inflate(data) : ''
123
131
  end
124
132
  end
125
133
 
126
134
  def [] x, y
135
+ x,y = adam7.convert_coords(x,y) if interlaced?
127
136
  scanlines[y][x]
128
137
  end
129
138
 
130
139
  def []= x, y, newpixel
131
140
  decode_all_scanlines
141
+ x,y = adam7.convert_coords(x,y) if interlaced?
132
142
  scanlines[y][x] = newpixel
133
143
  end
134
144
 
@@ -144,7 +154,8 @@ module ZPNG
144
154
  @scanlines ||=
145
155
  begin
146
156
  r = []
147
- height.to_i.times do |i|
157
+ n = interlaced? ? adam7.scanlines_count : height.to_i
158
+ n.times do |i|
148
159
  r << ScanLine.new(self,i)
149
160
  end
150
161
  r.delete_if(&:bad?)
@@ -154,7 +165,11 @@ module ZPNG
154
165
 
155
166
  def to_s h={}
156
167
  if scanlines.any?
157
- scanlines.map{ |l| l.to_s(h) }.join("\n")
168
+ if interlaced?
169
+ height.times.map{ |y| width.times.map{ |x| self[x,y].to_ascii(h) }.join }.join("\n")
170
+ else
171
+ scanlines.map{ |l| l.to_s(h) }.join("\n")
172
+ end
158
173
  else
159
174
  super()
160
175
  end
@@ -7,7 +7,7 @@ module ZPNG
7
7
  FILTER_AVERAGE = 3
8
8
  FILTER_PAETH = 4
9
9
 
10
- attr_accessor :image, :idx, :filter, :offset
10
+ attr_accessor :image, :idx, :filter, :offset, :bpp
11
11
 
12
12
  def initialize image, idx
13
13
  @image,@idx = image,idx
@@ -22,7 +22,12 @@ module ZPNG
22
22
  @decoded_bytes = "\x00" * (size-1)
23
23
  @filter = FILTER_NONE
24
24
  else
25
- @offset = idx*size
25
+ @offset =
26
+ if image.interlaced?
27
+ image.adam7.scanline_offset(idx)
28
+ else
29
+ idx*size
30
+ end
26
31
  if @filter = image.imagedata[@offset]
27
32
  @filter = @filter.ord
28
33
  else
@@ -39,28 +44,32 @@ module ZPNG
39
44
 
40
45
  # total scanline size in bytes, INCLUDING leading 'filter' byte
41
46
  def size
47
+ w =
48
+ if image.interlaced?
49
+ image.adam7.scanline_width(idx)
50
+ else
51
+ image.width
52
+ end
42
53
  if @BPP
43
- image.width*@BPP+1
54
+ w*@BPP+1
44
55
  else
45
- (image.width*@bpp/8.0+1).ceil
56
+ (w*@bpp/8.0+1).ceil
46
57
  end
47
58
  end
48
59
 
49
60
  def inspect
50
- "#<ZPNG::ScanLine " + (instance_variables-[:@image, :@decoded, :@BPP]).
51
- map{ |var| "#{var.to_s.tr('@','')}=#{instance_variable_get(var)}" }.
52
- join(", ") + ">"
61
+ if image.interlaced?
62
+ "#<ZPNG::ScanLine idx=%-2d offset=%-3d width=%-2d size=%-2d bpp=%d filter=%d>" %
63
+ [idx, offset, image.adam7.scanline_width(idx), size, bpp, filter]
64
+ else
65
+ "#<ZPNG::ScanLine idx=%-2d offset=%-3d size=%-2d bpp=%d filter=%d>" %
66
+ [idx, offset, size, bpp, filter]
67
+ end
53
68
  end
54
69
 
55
70
  def to_s h={}
56
- white = h[:white] || ' '
57
- black = h[:black] || '#'
58
- unknown = h[:unknown] || '?'
59
-
60
71
  @image.width.times.map do |i|
61
- px = decode_pixel(i)
62
- # printf "[d] %08x %s %s\n", px.to_i, px.inspect, px.to_s unless px.black?
63
- px.white?? white : (px.black?? black : unknown)
72
+ decode_pixel(i).to_ascii(h)
64
73
  end.join
65
74
  end
66
75
 
@@ -0,0 +1,11 @@
1
+ require 'rainbow'
2
+
3
+ class String
4
+ [:black, :red, :green, :yellow, :blue, :magenta, :cyan, :white].each do |color|
5
+ unless instance_methods.include?(color)
6
+ define_method color do
7
+ self.send(:color, color)
8
+ end
9
+ end
10
+ end
11
+ end
data/lib/zpng.rb CHANGED
@@ -1,13 +1,15 @@
1
1
  #!/usr/bin/env ruby
2
2
  require 'zlib'
3
3
  require 'stringio'
4
- require 'colorize'
4
+
5
+ require 'zpng/string_ext'
5
6
 
6
7
  require 'zpng/color'
7
8
  require 'zpng/block'
8
9
  require 'zpng/scan_line'
9
10
  require 'zpng/chunk'
10
11
  require 'zpng/image'
12
+ require 'zpng/adam7_decoder'
11
13
 
12
14
  # see alse http://github.com/wvanbergen/chunky_png/
13
15
 
@@ -0,0 +1,11 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe ZPNG::Color do
4
+
5
+ ZPNG::Color::ANSI_COLORS.each do |color_sym|
6
+ it "finds closest color for #{color_sym}" do
7
+ color = ZPNG::Color.const_get(color_sym.to_s.upcase)
8
+ color.closest_ansi_color.should == color_sym
9
+ end
10
+ end
11
+ end
data/spec/spec_helper.rb CHANGED
@@ -7,9 +7,6 @@ require 'zpng'
7
7
  # in ./support/ and its subdirectories.
8
8
  Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
9
9
 
10
- RSpec.configure do |config|
11
- end
12
-
13
10
  SAMPLES_DIR = File.join(
14
11
  File.dirname(
15
12
  File.dirname(
@@ -22,3 +19,32 @@ SAMPLES =
22
19
  else
23
20
  Dir[File.join(SAMPLES_DIR,'qr_*.png')]
24
21
  end
22
+
23
+ PNG_SUITE_URL = "http://www.schaik.com/pngsuite/PngSuite-2011apr25.tgz"
24
+
25
+ def get_png_suite
26
+ dir = File.join(SAMPLES_DIR, "png_suite")
27
+ if Dir.exist?(dir)
28
+ if Dir[File.join(dir, "*.png")].size > 100
29
+ # already fetched and unpacked
30
+ return
31
+ end
32
+ else
33
+ Dir.mkdir(dir)
34
+ end
35
+ require 'open-uri'
36
+ puts "[.] fetching PNG test-suite from #{PNG_SUITE_URL} .. "
37
+ data = open(PNG_SUITE_URL).read
38
+
39
+ fname = File.join(dir, "png_suite.tgz")
40
+ File.open(fname, "wb"){ |f| f<<data }
41
+ puts "[.] unpacking .. "
42
+ system "tar", "xzf", fname, "-C", dir
43
+ end
44
+
45
+ RSpec.configure do |config|
46
+ config.before :suite do
47
+ get_png_suite
48
+ end
49
+ end
50
+
data/zpng.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "zpng"
8
- s.version = "0.1.0"
8
+ s.version = "0.1.1"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Andrey \"Zed\" Zaikin"]
12
- s.date = "2012-12-10"
12
+ s.date = "2012-12-21"
13
13
  s.email = "zed.0xff@gmail.com"
14
14
  s.executables = ["zpng"]
15
15
  s.extra_rdoc_files = [
@@ -29,12 +29,14 @@ Gem::Specification.new do |s|
29
29
  "VERSION",
30
30
  "bin/zpng",
31
31
  "lib/zpng.rb",
32
+ "lib/zpng/adam7_decoder.rb",
32
33
  "lib/zpng/block.rb",
33
34
  "lib/zpng/chunk.rb",
34
35
  "lib/zpng/cli.rb",
35
36
  "lib/zpng/color.rb",
36
37
  "lib/zpng/image.rb",
37
38
  "lib/zpng/scan_line.rb",
39
+ "lib/zpng/string_ext.rb",
38
40
  "samples/captcha_4bpp.png",
39
41
  "samples/modify.rb",
40
42
  "samples/qr_aux_chunks.png",
@@ -46,6 +48,7 @@ Gem::Specification.new do |s|
46
48
  "samples/qr_rgb.png",
47
49
  "samples/qr_rgba.png",
48
50
  "spec/ascii_spec.rb",
51
+ "spec/color_spec.rb",
49
52
  "spec/create_image_spec.rb",
50
53
  "spec/crop_spec.rb",
51
54
  "spec/image_spec.rb",
@@ -65,21 +68,21 @@ Gem::Specification.new do |s|
65
68
  s.specification_version = 3
66
69
 
67
70
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
68
- s.add_runtime_dependency(%q<colorize>, [">= 0"])
69
71
  s.add_runtime_dependency(%q<hexdump>, [">= 0"])
72
+ s.add_runtime_dependency(%q<rainbow>, [">= 0"])
70
73
  s.add_development_dependency(%q<rspec>, [">= 2.8.0"])
71
74
  s.add_development_dependency(%q<bundler>, [">= 1.0.0"])
72
75
  s.add_development_dependency(%q<jeweler>, ["~> 1.8.4"])
73
76
  else
74
- s.add_dependency(%q<colorize>, [">= 0"])
75
77
  s.add_dependency(%q<hexdump>, [">= 0"])
78
+ s.add_dependency(%q<rainbow>, [">= 0"])
76
79
  s.add_dependency(%q<rspec>, [">= 2.8.0"])
77
80
  s.add_dependency(%q<bundler>, [">= 1.0.0"])
78
81
  s.add_dependency(%q<jeweler>, ["~> 1.8.4"])
79
82
  end
80
83
  else
81
- s.add_dependency(%q<colorize>, [">= 0"])
82
84
  s.add_dependency(%q<hexdump>, [">= 0"])
85
+ s.add_dependency(%q<rainbow>, [">= 0"])
83
86
  s.add_dependency(%q<rspec>, [">= 2.8.0"])
84
87
  s.add_dependency(%q<bundler>, [">= 1.0.0"])
85
88
  s.add_dependency(%q<jeweler>, ["~> 1.8.4"])
metadata CHANGED
@@ -2,19 +2,19 @@
2
2
  name: zpng
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.1.0
5
+ version: 0.1.1
6
6
  platform: ruby
7
7
  authors:
8
8
  - Andrey "Zed" Zaikin
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-12-10 00:00:00.000000000 Z
12
+ date: 2012-12-21 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  prerelease: false
16
16
  type: :runtime
17
- name: colorize
17
+ name: hexdump
18
18
  requirement: !ruby/object:Gem::Requirement
19
19
  requirements:
20
20
  - - ! '>='
@@ -30,7 +30,7 @@ dependencies:
30
30
  - !ruby/object:Gem::Dependency
31
31
  prerelease: false
32
32
  type: :runtime
33
- name: hexdump
33
+ name: rainbow
34
34
  requirement: !ruby/object:Gem::Requirement
35
35
  requirements:
36
36
  - - ! '>='
@@ -112,12 +112,14 @@ files:
112
112
  - VERSION
113
113
  - bin/zpng
114
114
  - lib/zpng.rb
115
+ - lib/zpng/adam7_decoder.rb
115
116
  - lib/zpng/block.rb
116
117
  - lib/zpng/chunk.rb
117
118
  - lib/zpng/cli.rb
118
119
  - lib/zpng/color.rb
119
120
  - lib/zpng/image.rb
120
121
  - lib/zpng/scan_line.rb
122
+ - lib/zpng/string_ext.rb
121
123
  - samples/captcha_4bpp.png
122
124
  - samples/modify.rb
123
125
  - samples/qr_aux_chunks.png
@@ -129,6 +131,7 @@ files:
129
131
  - samples/qr_rgb.png
130
132
  - samples/qr_rgba.png
131
133
  - spec/ascii_spec.rb
134
+ - spec/color_spec.rb
132
135
  - spec/create_image_spec.rb
133
136
  - spec/crop_spec.rb
134
137
  - spec/image_spec.rb
@@ -151,7 +154,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
151
154
  version: '0'
152
155
  segments:
153
156
  - 0
154
- hash: -488684070557161038
157
+ hash: 2879730800431969805
155
158
  none: false
156
159
  required_rubygems_version: !ruby/object:Gem::Requirement
157
160
  requirements: