zpng 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
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: