image_size 2.0.1 → 2.1.2

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
@@ -3,7 +3,3 @@
3
3
  source 'https://rubygems.org'
4
4
 
5
5
  gemspec
6
-
7
- if RUBY_VERSION >= '2.0'
8
- gem 'travis_check_rubies', '~> 0.2'
9
- end
data/LICENSE.txt ADDED
@@ -0,0 +1,56 @@
1
+ Ruby is copyrighted free software by Keisuke Minami <keisuke@rccn.com>.
2
+ You can redistribute it and/or modify it under either the terms of the GPL
3
+ version 2 (see the file GPL), or the conditions below:
4
+
5
+ 1. You may make and give away verbatim copies of the source form of the
6
+ software without restriction, provided that you duplicate all of the
7
+ original copyright notices and associated disclaimers.
8
+
9
+ 2. You may modify your copy of the software in any way, provided that
10
+ you do at least ONE of the following:
11
+
12
+ a) place your modifications in the Public Domain or otherwise
13
+ make them Freely Available, such as by posting said
14
+ modifications to Usenet or an equivalent medium, or by allowing
15
+ the author to include your modifications in the software.
16
+
17
+ b) use the modified software only within your corporation or
18
+ organization.
19
+
20
+ c) give non-standard binaries non-standard names, with
21
+ instructions on where to get the original software distribution.
22
+
23
+ d) make other distribution arrangements with the author.
24
+
25
+ 3. You may distribute the software in object code or binary form,
26
+ provided that you do at least ONE of the following:
27
+
28
+ a) distribute the binaries and library files of the software,
29
+ together with instructions (in the manual page or equivalent)
30
+ on where to get the original distribution.
31
+
32
+ b) accompany the distribution with the machine-readable source of
33
+ the software.
34
+
35
+ c) give non-standard binaries non-standard names, with
36
+ instructions on where to get the original software distribution.
37
+
38
+ d) make other distribution arrangements with the author.
39
+
40
+ 4. You may modify and include the part of the software into any other
41
+ software (possibly commercial). But some files in the distribution
42
+ are not written by the author, so that they are not under these terms.
43
+
44
+ For the list of those files and their copying conditions, see the
45
+ file LEGAL.
46
+
47
+ 5. The scripts and library files supplied as input to or produced as
48
+ output from the software do not automatically fall under the
49
+ copyright of the software, but belong to whomever generated them,
50
+ and may be sold commercially, and may be aggregated with this
51
+ software.
52
+
53
+ 6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
54
+ IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
55
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
56
+ PURPOSE.
data/README.markdown CHANGED
@@ -1,10 +1,10 @@
1
- [![Gem Version](https://img.shields.io/gem/v/image_size.svg?style=flat)](https://rubygems.org/gems/image_size)
2
- [![Build Status](https://img.shields.io/travis/toy/image_size/master.svg?style=flat)](https://travis-ci.org/toy/image_size)
1
+ [![Gem Version](https://img.shields.io/gem/v/image_size?logo=rubygems)](https://rubygems.org/gems/image_size)
2
+ [![Build Status](https://img.shields.io/github/workflow/status/toy/image_size/check/master?logo=github)](https://github.com/toy/image_size/actions/workflows/check.yml)
3
3
 
4
4
  # image_size
5
5
 
6
6
  measure image size using pure Ruby
7
- formats: `apng`, `bmp`, `cur`, `gif`, `jpeg`, `ico`, `mng`, `pbm`, `pcx`, `pgm`, `png`, `ppm`, `psd`, `swf`, `tiff`, `xbm`, `xpm`, `webp`
7
+ formats: `apng`, `bmp`, `cur`, `gif`, `ico`, `j2c`, `jp2`, `jpeg`, `jpx`, `mng`, `pam`, `pbm`, `pcx`, `pgm`, `png`, `ppm`, `psd`, `svg`, `swf`, `tiff`, `webp`, `xbm`, `xpm`
8
8
 
9
9
  ## Installation
10
10
 
@@ -85,9 +85,7 @@ end
85
85
 
86
86
  ## Licence
87
87
 
88
- This code is free to use under the terms of the Ruby's licence.
88
+ This code is free to use under the terms of the [Ruby's licence](LICENSE.txt).
89
89
 
90
- ## Contact
91
-
92
- Original author: "Keisuke Minami": mailto:keisuke@rccn.com
93
- Further development by Ivan Kuchin https://github.com/toy/image_size
90
+ Original author: Keisuke Minami <keisuke@rccn.com>.\
91
+ Further development 2010-2020 Ivan Kuchin https://github.com/toy/image_size
data/image_size.gemspec CHANGED
@@ -2,15 +2,13 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = 'image_size'
5
- s.version = '2.0.1'
5
+ s.version = '2.1.2'
6
6
  s.summary = %q{Measure image size using pure Ruby}
7
- s.description = %q{Measure following file dimensions: apng, bmp, cur, gif, jpeg, ico, mng, pbm, pcx, pgm, png, ppm, psd, swf, tiff, xbm, xpm, webp}
8
- s.homepage = "http://github.com/toy/#{s.name}"
7
+ s.description = %q{Measure following file dimensions: apng, bmp, cur, gif, ico, j2c, jp2, jpeg, jpx, mng, pam, pbm, pcx, pgm, png, ppm, psd, svg, swf, tiff, webp, xbm, xpm}
8
+ s.homepage = "https://github.com/toy/#{s.name}"
9
9
  s.authors = ['Keisuke Minami', 'Ivan Kuchin']
10
10
  s.license = 'Ruby'
11
11
 
12
- s.rubyforge_project = s.name
13
-
14
12
  s.metadata = {
15
13
  'bug_tracker_uri' => "https://github.com/toy/#{s.name}/issues",
16
14
  'changelog_uri' => "https://github.com/toy/#{s.name}/blob/master/CHANGELOG.markdown",
@@ -24,7 +22,7 @@ Gem::Specification.new do |s|
24
22
  s.require_paths = %w[lib]
25
23
 
26
24
  s.add_development_dependency 'rspec', '~> 3.0'
27
- if RUBY_VERSION >= '2.2'
28
- s.add_development_dependency 'rubocop', '~> 0.59'
25
+ if RUBY_VERSION >= '2.4'
26
+ s.add_development_dependency 'rubocop', '~> 1.0'
29
27
  end
30
28
  end
data/lib/image_size.rb CHANGED
@@ -17,6 +17,7 @@ class ImageSize
17
17
 
18
18
  class ImageReader # :nodoc:
19
19
  attr_reader :data
20
+
20
21
  def initialize(data_or_io)
21
22
  @io = if data_or_io.is_a?(String)
22
23
  StringIO.new(data_or_io)
@@ -84,28 +85,28 @@ class ImageSize
84
85
  private
85
86
 
86
87
  SVG_R = /<svg\b([^>]*)>/.freeze
88
+ XML_R = /<\?xml|<!--/.freeze
87
89
  def detect_format(ir)
88
90
  head = ir[0, 1024]
89
91
  case
90
- when head[0, 6] =~ /GIF8[79]a/ then :gif
91
- when head[0, 8] == "\211PNG\r\n\032\n" then detect_png_type(ir)
92
- when head[0, 8] == "\212MNG\r\n\032\n" then :mng
93
- when head[0, 2] == "\377\330" then :jpeg
94
- when head[0, 2] == 'BM' then :bmp
95
- when head[0, 2] =~ /P[1-7]/ then :ppm
96
- when head =~ /\#define\s+\S+\s+\d+/ then :xbm
97
- when head[0, 4] == "II*\000" then :tiff
98
- when head[0, 4] == "MM\000*" then :tiff
99
- when head =~ %r{/\* XPM \*/} then :xpm
100
- when head[0, 4] == '8BPS' then :psd
101
- when head[0, 3] =~ /[FC]WS/ then :swf
102
- when head[SVG_R] ||
103
- head =~ /<\?xml|<!--/ && ir[0, 4096][SVG_R]
104
- then :svg
105
- when head[0, 2] =~ /\n[\000-\005]/ then :pcx
106
- when head[0, 12] =~ /RIFF(?m:....)WEBP/ then :webp
107
- when head[0, 4] == "\000\000\001\000" then :ico
108
- when head[0, 4] == "\000\000\002\000" then :cur
92
+ when head[0, 6] =~ /GIF8[79]a/ then :gif
93
+ when head[0, 8] == "\211PNG\r\n\032\n" then detect_png_type(ir)
94
+ when head[0, 8] == "\212MNG\r\n\032\n" then :mng
95
+ when head[0, 2] == "\377\330" then :jpeg
96
+ when head[0, 2] == 'BM' then :bmp
97
+ when head[0, 3] =~ /P[1-6]\s|P7\n/ then detect_pnm_type(ir)
98
+ when head =~ /\#define\s+\S+\s+\d+/ then :xbm
99
+ when %W[II*\0 MM\0*].include?(head[0, 4]) then :tiff
100
+ when head =~ %r{/\* XPM \*/} then :xpm
101
+ when head[0, 4] == '8BPS' then :psd
102
+ when head[0, 3] =~ /[FC]WS/ then :swf
103
+ when head =~ SVG_R || (head =~ XML_R && ir[0, 4096][SVG_R]) then :svg
104
+ when head[0, 2] =~ /\n[\0-\5]/ then :pcx
105
+ when head[0, 12] =~ /RIFF(?m:....)WEBP/ then :webp
106
+ when head[0, 4] == "\0\0\1\0" then :ico
107
+ when head[0, 4] == "\0\0\2\0" then :cur
108
+ when head[0, 12] == "\0\0\0\fjP \r\n\207\n" then detect_jpeg2000_type(ir)
109
+ when head[0, 4] == "\377O\377Q" then :j2c
109
110
  end
110
111
  end
111
112
 
@@ -122,6 +123,26 @@ private
122
123
  :png
123
124
  end
124
125
 
126
+ def detect_pnm_type(ir)
127
+ case ir[0, 2]
128
+ when 'P1', 'P4' then :pbm
129
+ when 'P2', 'P5' then :pgm
130
+ when 'P3', 'P6' then :ppm
131
+ when 'P7' then :pam
132
+ end
133
+ end
134
+
135
+ def detect_jpeg2000_type(ir)
136
+ return unless ir[16, 4] == 'ftyp'
137
+
138
+ # using xl-box would be weird, but doesn't seem to contradict specification
139
+ skip = ir[12, 4] == "\0\0\0\1" ? 16 : 8
140
+ case ir[12 + skip, 4]
141
+ when 'jp2 ' then :jp2
142
+ when 'jpx ' then :jpx
143
+ end
144
+ end
145
+
125
146
  def size_of_gif(ir)
126
147
  ir[6, 4].unpack('vv')
127
148
  end
@@ -143,11 +164,11 @@ private
143
164
  end
144
165
  alias_method :size_of_apng, :size_of_png
145
166
 
146
- JPEG_CODE_CHECK = %W[
147
- \xC0 \xC1 \xC2 \xC3
148
- \xC5 \xC6 \xC7
149
- \xC9 \xCA \xCB
150
- \xCD \xCE \xCF
167
+ JPEG_CODE_CHECK = [
168
+ 0xC0, 0xC1, 0xC2, 0xC3,
169
+ 0xC5, 0xC6, 0xC7,
170
+ 0xC9, 0xCA, 0xCB,
171
+ 0xCD, 0xCE, 0xCF
151
172
  ].freeze
152
173
  def size_of_jpeg(ir)
153
174
  section_marker = "\xFF"
@@ -157,7 +178,7 @@ private
157
178
  offset += 1 until section_marker != ir[offset + 1, 1]
158
179
  raise FormatError, 'EOF in JPEG' if ir[offset, 1].nil?
159
180
 
160
- _marker, code, length = ir[offset, 4].unpack('aan')
181
+ _marker, code, length = ir[offset, 4].unpack('aCn')
161
182
  offset += 4
162
183
 
163
184
  if JPEG_CODE_CHECK.include?(code)
@@ -187,12 +208,38 @@ private
187
208
  header = ir[0, 1024]
188
209
  header.gsub!(/^\#[^\n\r]*/m, '')
189
210
  header =~ /^(P[1-6])\s+?(\d+)\s+?(\d+)/m
190
- case $1
191
- when 'P1', 'P4' then @format = :pbm
192
- when 'P2', 'P5' then @format = :pgm
193
- end
194
211
  [$2.to_i, $3.to_i]
195
212
  end
213
+ alias_method :size_of_pbm, :size_of_ppm
214
+ alias_method :size_of_pgm, :size_of_ppm
215
+
216
+ def size_of_pam(ir)
217
+ width = height = nil
218
+ offset = 3
219
+ loop do
220
+ if ir[offset, 1] == '#'
221
+ offset += 1 until ["\n", '', nil].include?(ir[offset, 1])
222
+ offset += 1
223
+ else
224
+ chunk = ir[offset, 32]
225
+ case chunk
226
+ when /\AWIDTH (\d+)\n/
227
+ width = $1.to_i
228
+ when /\AHEIGHT (\d+)\n/
229
+ height = $1.to_i
230
+ when /\AENDHDR\n/
231
+ break
232
+ when /\A(?:DEPTH|MAXVAL) \d+\n/, /\ATUPLTYPE \S+\n/
233
+ # ignore
234
+ else
235
+ raise FormatError, "Unexpected data in PAM header: #{chunk.inspect}"
236
+ end
237
+ offset += $&.length
238
+ break if width && height
239
+ end
240
+ end
241
+ [width, height]
242
+ end
196
243
 
197
244
  def size_of_xbm(ir)
198
245
  ir[0, 1024] =~ /^\#define\s*\S*\s*(\d+)\s*\n\#define\s*\S*\s*(\d+)/mi
@@ -247,7 +294,7 @@ private
247
294
  end
248
295
 
249
296
  def size_of_pcx(ir)
250
- parts = ir[4, 8].unpack('S4')
297
+ parts = ir[4, 8].unpack('v4')
251
298
  [parts[2] - parts[0] + 1, parts[3] - parts[1] + 1]
252
299
  end
253
300
 
@@ -255,7 +302,7 @@ private
255
302
  value_bit_length = ir[8, 1].unpack('B5').first.to_i(2)
256
303
  bit_length = 5 + value_bit_length * 4
257
304
  rect_bits = ir[8, bit_length / 8 + 1].unpack("B#{bit_length}").first
258
- values = rect_bits.unpack('@5' + "a#{value_bit_length}" * 4).map{ |bits| bits.to_i(2) }
305
+ values = rect_bits[5..-1].unpack("a#{value_bit_length}" * 4).map{ |bits| bits.to_i(2) }
259
306
  x_min, x_max, y_min, y_max = values
260
307
  [(x_max - x_min) / 20, (y_max - y_min) / 20]
261
308
  end
@@ -299,4 +346,44 @@ private
299
346
  [(w16 | w8 << 16) + 1, (h16 | h8 << 16) + 1]
300
347
  end
301
348
  end
349
+
350
+ def size_of_jp2(ir)
351
+ offset = 12
352
+ stop = nil
353
+ in_header = false
354
+ loop do
355
+ break if stop && offset >= stop
356
+ break if ir[offset, 4] == '' || ir[offset, 4].nil?
357
+
358
+ size = ir[offset, 4].unpack('N')[0]
359
+ type = ir[offset + 4, 4]
360
+
361
+ data_offset = 8
362
+ case size
363
+ when 1
364
+ size = ir[offset, 8].unpack('Q>')[0]
365
+ data_offset = 16
366
+ raise FormatError, "Unexpected xl-box size #{size}" if (1..15).include?(size)
367
+ when 2..7
368
+ raise FormatError, "Reserved box size #{size}"
369
+ end
370
+
371
+ if type == 'jp2h'
372
+ stop = offset + size unless size.zero?
373
+ offset += data_offset
374
+ in_header = true
375
+ elsif in_header && type == 'ihdr'
376
+ return ir[offset + data_offset, 8].unpack('NN').reverse
377
+ else
378
+ break if size.zero? # box to the end of file
379
+
380
+ offset += size
381
+ end
382
+ end
383
+ end
384
+ alias_method :size_of_jpx, :size_of_jp2
385
+
386
+ def size_of_j2c(ir)
387
+ ir[8, 8].unpack('NN')
388
+ end
302
389
  end
@@ -5,7 +5,12 @@ require 'image_size'
5
5
  require 'tempfile'
6
6
 
7
7
  describe ImageSize do
8
+ max_filesize = 16_384
9
+
8
10
  (Dir['spec/images/*/*.*'] + [__FILE__]).each do |path|
11
+ filesize = File.size(path)
12
+ warn "#{path} is too big #{filesize} (max #{max_filesize})" if filesize > max_filesize
13
+
9
14
  describe "for #{path}" do
10
15
  let(:name){ File.basename(path) }
11
16
  let(:attributes) do
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
File without changes
@@ -0,0 +1,8 @@
1
+ P7
2
+ WIDTH 22
3
+ HEIGHT 25
4
+ DEPTH 3
5
+ MAXVAL 255
6
+ TUPLTYPE RGB
7
+ ENDHDR
8
+ JMRGJONQVKNSRVZY^b{��|��osyz����Ǎ��v|�������UY_ORT�^_�ts�_b`FH�`aDGLHJPJMQfjnflplqu}�����u{�������nsw[`d]bgqv}aej>AFLLO�`c�ro�bdxORlsvZ_ccknS[^imrwz��������������ɑ��UY]���u{~��glosz~X^b�_^�li�lk���dimORWORWRUZY\a������������������UW\������]`ehmqOPU>AHfOR�lj�kjv}�KNSKOREILEIMTX[LQUAEJHJOZ]a_di���muz������=<BSUZrv|���}pt�jh�liPWZGJOIMPEILDHK=AE`eiuz~������}��������������XZ_MMR[^e�������ed�heHKPPSWFKNAFIMRV`hk���������nuxW\`V[_CHLu|����[^dBBGDHMBEJomr�hf�geJMSZ\aDILekn������dimPUYMNSBBGCDIFGLDEJ]`f���chlDGLT\^EMQ]MQ�ji�ecoehXadJMR���Y]a_afcdjORWKNTMTYJNRFFICCG]`d���z�==BFGLAEK�VX�ki�ec�nrLQWNSZdjmkqtBBHABGPX]^ltScgIMPCDHJJNQTX�����JKPPSX_^d�__�jf�ca�st�_bjX[jsw���^eh=@EIPUQX^RW\UY]JNR@AEegn���v{FFLmuy�]_�ec�gd�ca�zx�zx�po�cg~����y��YZ^CEIEGKSUZejnMRUZ]b���osxADIm[_�_`�ca�ec�db�st�|}�zy�vt�gh�ot�����Ϣ��ehlEGLX]`PRVX[_���dek7<@�RT�b_�a_�`^�ca�ux�{~�|z�yv�{w�rp�ii�����������ntwDDIgjn���`cjSSW�^^�gd�b`�`^�b`�yv�wx�xu�|x�yu�vs�vs�oo�ii�km������FHMimq���QX_x`d�fe�fb�da�b`�ca�wu�rp�vt�us�tr�vs�ts�sr�po�uv�ml�x|V[_gin���OU[�Z\�fc�ea�db�ca�b`�zx�tq�vt�us�wt�vs�wt�sq�rr�st�sq�giTX\SVZ���fbg�ce�eb�ca�ec�db�ec�yu�ur�sq�sr�vs�xu�xs�tq�xt�ws�xt�ihKMRchm���]NP�ge�eb�ca�db�ec�fd�zv�sq�rq�sr�rp�xu�so�rp�tq�qn�uq�bcHIN\bgo|�wQU�jh�fd�ca�b`�ca�ec�zy�xt�tr�vs�sr�sr�tq�sp�rp�kj�mk�^^HLPLOTfqv�UV�jf�ec�db�b`�cb�ca�ss�{w�us�tr�ur�wt�tq�qo�ro�lj�on�ZZ=BFNNTRZ_�YY�ie�db�db�`_�_^�`_�ij�~|�vs�ur�sq�pn�qo�ol�ji�mj�qn�Z]CFL]_dLIN�aa�fb�ca�cb�a`�__�]^x_^�{x�ws�wt�sp�pn�po�lknZ^�lk�pmxXYDINkrwkUX�mj�db�fdX[�Y\�`_�]]�gi�vs�us�xu�tr�nk�lj�nk�jj�mk�kjlPR?CGGIP�bb�pm�fd�da�Y\�]]�b_�`_�ru�ml�ur�wu�tr�pk�lg�oi�oj�pl�kiaMO;@EPGI�kj�he�fd�fc�b`�a^�b`�_^
Binary file
@@ -0,0 +1,4 @@
1
+ P5
2
+ 22 25
3
+ 255
4
+ MJQNU]��sÑ{��YRh�mLmGJMikp��z��r_aueALi�rXr^jZmz����ŗX�z�ky]k��hRRU\������W��`lPAT~|NNHHWPEJ]c�t��=Uv�s|VJLHG@dy�������ZM^��v|KSJEQg���t[ZG{�^BHEnx{M\Hj��hTNBDGE`�gGZLQ}yg_M�\adRNSMFC`�~=GE_yzPRipBBWj`LDJT��KS_n~w�i\q�d@OWVXMAg�zFtgz{w���j��ZEGUiQ]�sD_rwyx|���ss�ͩhG\R[�e;]wutw������u����sDj�cSm{vtv��������{w��Hl�We{zxvw����������~{Zi�Te{yxwv�����������qWV�ctywyxy�����������rMg�Qzywxyz�����������lIazY~zwvwy���������~�gKOo_yxvww~���������cANYe~xxutup�������w�cF_Jq{wxvtsd������x_�_HqZ�xzahvrm�����{�~VBIl�zweowu{{�������~Q?I||zzwuvt
@@ -0,0 +1,4 @@
1
+ P6
2
+ 22 25
3
+ 255
4
+ JMRGJONQVKNSRVZY^b{��|��osyz����Ǎ��v|�������UY_ORT�^_�ts�_b`FH�`aDGLHJPJMQfjnflplqu}�����u{�������nsw[`d]bgqv}aej>AFLLO�`c�ro�bdxORlsvZ_ccknS[^imrwz��������������ɑ��UY]���u{~��glosz~X^b�_^�li�lk���dimORWORWRUZY\a������������������UW\������]`ehmqOPU>AHfOR�lj�kjv}�KNSKOREILEIMTX[LQUAEJHJOZ]a_di���muz������=<BSUZrv|���}pt�jh�liPWZGJOIMPEILDHK=AE`eiuz~������}��������������XZ_MMR[^e�������ed�heHKPPSWFKNAFIMRV`hk���������nuxW\`V[_CHLu|����[^dBBGDHMBEJomr�hf�geJMSZ\aDILekn������dimPUYMNSBBGCDIFGLDEJ]`f���chlDGLT\^EMQ]MQ�ji�ecoehXadJMR���Y]a_afcdjORWKNTMTYJNRFFICCG]`d���z�==BFGLAEK�VX�ki�ec�nrLQWNSZdjmkqtBBHABGPX]^ltScgIMPCDHJJNQTX�����JKPPSX_^d�__�jf�ca�st�_bjX[jsw���^eh=@EIPUQX^RW\UY]JNR@AEegn���v{FFLmuy�]_�ec�gd�ca�zx�zx�po�cg~����y��YZ^CEIEGKSUZejnMRUZ]b���osxADIm[_�_`�ca�ec�db�st�|}�zy�vt�gh�ot�����Ϣ��ehlEGLX]`PRVX[_���dek7<@�RT�b_�a_�`^�ca�ux�{~�|z�yv�{w�rp�ii�����������ntwDDIgjn���`cjSSW�^^�gd�b`�`^�b`�yv�wx�xu�|x�yu�vs�vs�oo�ii�km������FHMimq���QX_x`d�fe�fb�da�b`�ca�wu�rp�vt�us�tr�vs�ts�sr�po�uv�ml�x|V[_gin���OU[�Z\�fc�ea�db�ca�b`�zx�tq�vt�us�wt�vs�wt�sq�rr�st�sq�giTX\SVZ���fbg�ce�eb�ca�ec�db�ec�yu�ur�sq�sr�vs�xu�xs�tq�xt�ws�xt�ihKMRchm���]NP�ge�eb�ca�db�ec�fd�zv�sq�rq�sr�rp�xu�so�rp�tq�qn�uq�bcHIN\bgo|�wQU�jh�fd�ca�b`�ca�ec�zy�xt�tr�vs�sr�sr�tq�sp�rp�kj�mk�^^HLPLOTfqv�UV�jf�ec�db�b`�cb�ca�ss�{w�us�tr�ur�wt�tq�qo�ro�lj�on�ZZ=BFNNTRZ_�YY�ie�db�db�`_�_^�`_�ij�~|�vs�ur�sq�pn�qo�ol�ji�mj�qn�Z]CFL]_dLIN�aa�fb�ca�cb�a`�__�]^x_^�{x�ws�wt�sp�pn�po�lknZ^�lk�pmxXYDINkrwkUX�mj�db�fdX[�Y\�`_�]]�gi�vs�us�xu�tr�nk�lj�nk�jj�mk�kjlPR?CGGIP�bb�pm�fd�da�Y\�]]�b_�`_�ru�ml�ur�wu�tr�pk�lg�oi�oj�pl�kiaMO;@EPGI�kj�he�fd�fc�b`�a^�b`�_^
@@ -0,0 +1,27 @@
1
+ P1
2
+ 22 25
3
+ 1 1 1 1 1 1 1 0 1 0 0 0 0 0 0 1 1 1 1 1 1 1
4
+ 1 1 1 1 1 1 0 0 1 0 0 0 0 1 0 1 1 1 1 1 1 1
5
+ 1 1 1 1 1 1 0 0 0 0 0 0 1 0 1 0 1 1 1 1 1 0
6
+ 1 1 1 1 1 1 0 0 0 0 0 0 1 0 0 1 1 1 1 1 0 1
7
+ 1 1 1 1 1 1 1 1 1 1 1 0 1 0 0 1 1 1 1 1 1 0
8
+ 1 1 1 1 1 1 1 1 0 0 1 1 0 0 0 1 1 1 0 0 1 1
9
+ 1 1 1 1 1 1 0 0 0 1 1 1 1 0 0 1 1 1 1 1 0 1
10
+ 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 0
11
+ 1 1 1 0 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1
12
+ 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1
13
+ 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 0 0 0
14
+ 0 1 0 1 1 0 0 0 1 1 1 1 1 0 0 0 1 1 1 1 1 1
15
+ 1 0 0 0 1 1 0 0 0 1 1 1 1 1 0 1 1 1 1 1 0 1
16
+ 0 0 1 0 0 0 1 0 0 0 1 1 1 1 0 1 1 1 1 1 1 1
17
+ 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 1 1 1 0 1 1 0
18
+ 0 0 1 0 1 0 0 0 1 0 1 1 1 1 0 1 1 0 1 0 1 1
19
+ 1 0 0 1 0 1 0 0 1 0 0 1 1 1 0 1 1 1 0 1 1 0
20
+ 0 0 0 0 0 0 0 1 0 0 0 1 1 1 1 1 1 0 1 0 0 1
21
+ 1 0 1 1 0 1 0 1 0 1 0 1 1 1 1 1 0 1 1 1 0 1
22
+ 0 0 0 0 0 0 0 0 0 1 0 1 1 1 1 1 1 0 0 1 1 1
23
+ 1 0 0 1 1 0 1 0 0 1 0 1 1 1 1 1 1 0 0 1 1 1
24
+ 1 0 0 0 0 0 0 1 0 1 1 1 1 1 1 1 0 1 1 1 0 1
25
+ 1 0 0 0 0 1 0 1 1 0 1 1 1 1 1 0 1 0 1 1 1 1
26
+ 1 0 1 0 0 0 1 0 1 1 1 1 1 1 1 1 0 1 1 1 0 0
27
+ 1 0 0 1 0 0 1 0 1 0 1 1 1 1 1 1 1 1 0 1 1 0
@@ -0,0 +1,28 @@
1
+ P2
2
+ 22 25
3
+ 255
4
+ 77 74 81 78 85 93 129 129 115 127 195 145 123 169 147 89 82 104 135 109 76 109
5
+ 71 74 77 105 107 112 132 169 122 151 204 114 95 97 117 101 65 76 105 133 114 88
6
+ 114 94 106 90 109 122 165 164 178 187 197 151 88 134 122 130 107 121 93 107 128 127
7
+ 158 104 82 82 85 92 144 155 154 180 157 183 87 182 145 96 108 80 65 84 127 126
8
+ 124 78 78 72 72 87 80 69 74 93 99 157 116 160 139 61 85 118 141 115 124 127
9
+ 86 74 76 72 71 64 100 121 139 170 132 142 154 182 160 90 77 94 142 145 118 124
10
+ 75 83 74 69 81 103 137 170 158 116 91 90 71 123 173 94 66 72 69 110 120 123
11
+ 77 92 72 106 138 140 104 84 78 66 68 71 69 96 161 103 71 90 76 81 125 121
12
+ 103 95 77 134 92 97 100 82 78 83 77 70 67 96 185 126 61 71 69 95 127 121
13
+ 122 80 82 105 112 66 66 87 106 96 76 68 74 84 180 130 75 83 95 110 126 119
14
+ 131 105 92 113 140 100 64 79 87 86 88 77 65 103 189 122 70 116 103 122 123 119
15
+ 138 138 128 106 127 158 128 90 69 71 85 105 81 93 191 115 68 95 114 119 121 120
16
+ 124 142 140 137 115 115 168 205 169 104 71 92 82 91 185 101 59 93 119 117 116 119
17
+ 131 140 140 138 140 131 117 132 146 166 148 115 68 106 192 99 83 109 123 118 116 118
18
+ 138 137 137 140 138 135 136 129 123 119 138 140 72 108 178 87 101 123 122 120 118 119
19
+ 136 132 136 135 134 135 134 134 128 133 126 123 90 105 177 84 101 123 121 120 119 118
20
+ 138 134 136 135 136 135 136 133 131 132 134 113 87 86 163 99 116 121 119 121 120 121
21
+ 137 134 133 133 135 137 137 134 137 136 138 114 77 103 147 81 122 121 119 120 121 122
22
+ 139 133 132 132 129 137 132 132 134 131 135 108 73 97 122 89 126 122 119 118 119 121
23
+ 137 137 134 135 133 133 134 133 132 126 129 103 75 79 111 95 127 121 120 118 119 119
24
+ 126 140 135 134 134 136 134 131 133 127 131 99 65 78 89 101 126 120 120 117 116 117
25
+ 112 143 135 134 133 130 132 129 119 127 133 99 70 95 74 113 123 119 120 118 116 115
26
+ 100 139 136 136 133 131 132 120 95 127 132 95 72 113 90 128 120 122 97 104 118 114
27
+ 109 133 135 137 134 128 127 127 123 128 126 86 66 73 108 131 122 119 101 111 119 117
28
+ 123 123 135 136 134 130 127 129 129 130 126 81 63 73 124 124 122 122 119 117 118 116