Module Origami::Filter::Predictor
In: sources/parser/filters.rb

Methods

Constants

NONE = 1
TIFF = 2
PNG_NONE = 10
PNG_SUB = 11
PNG_UP = 12
PNG_AVERAGE = 13
PNG_PAETH = 14
PNG_OPTIMUM = 15

Public Class methods

[Source]

     # File sources/parser/filters.rb, line 117
117:       def self.do_png_post_prediction(data, bpp, bpr)
118: 
119:         result = ""
120:         uprow = thisrow = "\0" * bpr
121:         ncols = data.size / bpr
122:         
123:         ncols.times do |col|
124: 
125:           line = data[col * bpr, bpr]
126:           predictor = 10 + line[0]
127: 
128:           for i in (bpp..bpr-1)
129: 
130:             up = uprow[i]
131:             left = thisrow[i-bpp]
132:             upleft = uprow[i-bpp]
133: 
134:             case predictor
135:               when PNG_NONE
136:                 thisrow = line 
137:               when PNG_SUB
138:                 thisrow[i] = ((line[i] + left) & 0xFF).chr
139:               when PNG_UP
140:                 thisrow[i] = ((line[i] + up) & 0xFF).chr
141:               when PNG_AVERAGE
142:                 thisrow[i] = ((line[i] + ((left + up) / 2)) & 0xFF).chr
143:               when PNG_PAETH
144:                 p = left + up - upleft
145:                 pa, pb, pc = (p - left).abs, (p - up).abs, (p - upleft).abs
146: 
147:                 thisrow[i] = ((line[i] + 
148:                 case [ pa, pb, pc ].min
149:                   when pa then left
150:                   when pb then up
151:                   when pc then upleft
152:                 end
153:                 ) & 0xFF).chr
154:             else
155:               puts "Unknown PNG predictor : #{predictor}"
156:               thisrow = line
157:             end
158:             
159:           end
160: 
161:           result << thisrow[bpp..-1]
162:           uprow = thisrow
163:         end
164:   
165:         result
166:       end

[Source]

     # File sources/parser/filters.rb, line 168
168:       def self.do_png_pre_prediction(data, predictor, bpp, bpr)
169:         
170:         result = ""
171:         ncols = data.size / bpr
172: 
173:         line = "\0" * bpp + data[-bpr, bpr]
174:         
175:         (ncols-1).downto(0) do |col|
176: 
177:           uprow = col.zero? ? ("\0" * (bpr+bpp)) : ("\0" * bpp + data[(col-1)*bpr,bpr])
178:           (bpr+bpp-1).downto(bpp) do |i|
179: 
180:             up = uprow[i]
181:             left = line[i-bpp]
182:             upleft = uprow[i-bpp]
183: 
184:             case predictor
185:               when PNG_SUB
186:                 line[i] = ((line[i] - left) & 0xFF).chr
187:               when PNG_UP
188:                 line[i] = ((line[i] - up) & 0xFF).chr
189:               when PNG_AVERAGE
190:                 line[i] = ((line[i] - ((left + up) / 2)) & 0xFF).chr
191:               when PNG_PAETH
192:                 p = left + up - upleft
193:                 pa, pb, pc = (p - left).abs, (p - up).abs, (p - upleft).abs
194: 
195:                 line[i] = ((line[i] - 
196:                 case [ pa, pb, pc ].min
197:                   when pa then left
198:                   when pb then up
199:                   when pc then upleft
200:                 end
201:                 ) & 0xFF).chr
202:               when PNG_NONE
203:             else
204:               puts "Unknown PNG predictor : #{predictor}"
205:             end
206:             
207:           end
208:           
209:           line[0] = (predictor - 10).chr
210:           result = line + result
211:           
212:           line = uprow
213:         end
214:   
215:         result
216:       end

[Source]

     # File sources/parser/filters.rb, line 83
 83:       def self.do_post_prediction(data, predictor = NONE, colors = 1, bpc = 8, columns = 1)
 84: 
 85:         return data if predictor == NONE
 86: 
 87:         unless (1..4) === colors
 88:           raise PredictorError, "Colors must be between 1 and 4"
 89:         end
 90: 
 91:         unless [1,2,4,8,16].include?(bpc)
 92:           raise PredictorError, "BitsPerComponent must be in 1, 2, 4, 8 or 16"
 93:         end
 94: 
 95:         # components per line
 96:         nvals = columns * colors
 97: 
 98:         # bytes per pixel
 99:         bpp = (colors * bpc + 7) >> 3
100: 
101:         # bytes per row
102:         bpr = ((nvals * bpc + 7) >> 3) + bpp
103: 
104:         unless data.size % bpr == 0
105:           raise PredictorError, "Invalid data size"
106:         end
107: 
108:         if predictor == TIFF
109:           raise PredictorError, "TIFF prediction not yet supported"
110:         elsif predictor >= 10 # PNG
111:           do_png_post_prediction(data, bpp, bpr)
112:         else
113:           raise PredictorError, "Unknown predictor"
114:         end
115:       end

[Source]

    # File sources/parser/filters.rb, line 49
49:       def self.do_pre_prediction(data, predictor = NONE, colors = 1, bpc = 8, columns = 1)
50:       
51:         return data if predictor == NONE
52: 
53:         unless (1..4) === colors.to_i
54:           raise PredictorError, "Colors must be between 1 and 4"
55:         end
56: 
57:         unless [1,2,4,8,16].include?(bpc.to_i)
58:           raise PredictorError, "BitsPerComponent must be in 1, 2, 4, 8 or 16"
59:         end
60: 
61:         # components per line
62:         nvals = columns * colors
63: 
64:         # bytes per pixel
65:         bpp = (colors * bpc + 7) >> 3
66: 
67:         # bytes per row
68:         bpr = (nvals * bpc + 7) >> 3
69: 
70:         unless data.size % bpr == 0
71:           raise PredictorError, "Invalid data size"
72:         end
73: 
74:         if predictor == TIFF
75:           raise PredictorError, "TIFF prediction not yet supported"
76:         elsif predictor >= 10 # PNG
77:           do_png_pre_prediction(data, predictor, bpp, bpr)
78:         else
79:           raise PredictorError, "Unknown predictor"
80:         end
81:      end

[Validate]