[Coco] Now you can convert CM3 files without screenshots !
Mathieu Bouchard
matju at artengine.ca
Sun Oct 22 15:28:57 EDT 2017
Here is a program I just wrote (in the Ruby language) for decoding CM3 files.
You can put the following listing in a text file named cm3toppm and then run a
command such as this from the Terminal (if you have netpbm) :
ruby cm3toppm < WHATEVER.CM3 | pnmtopng -compression 9 > WHATEVER.PNG
If you have ImageMagick instead, you would write :
ruby cm3toppm < WHATEVER.CM3 | convert - WHATEVER.PNG
You may also just output a PPM file :
ruby cm3toppm < WHATEVER.CM3 > WHATEVER.PPM
the listing starts after the dashed line :
-----------------8<--------découpez-ici--------8<-----------------
#!/usr/bin/env ruby
# encoding: utf-8
# cm3toppm - decoder for cm3 (CoCoMax 3) format
# Copyright (c) 2017 by Mathieu Bouchard
# reads cm3 from stdin, outputs ppm that can be piped
# to cjpeg (.jpg) from jpeg-tools, or to pnmtopng (.png) from netpbm.
def debug(x) STDERR.puts x end
def dump(x) c=$palette[x]; STDOUT.write [(c[5]*2+c[2])*85,(c[4]*2+c[1])*85,(c[3]*2+c[0])*85].pack("ccc") end
f=STDIN; f.set_encoding("ASCII-8BIT")
cols=320; pictyp=f.read(1).ord; rows=(pictyp[7]+1)*192; sans_motifs=pictyp[0]!=0
debug "#{cols}x#{rows}, 16 couleurs, sans_motifs=#{sans_motifs}"
$palette=[]; 16.times {$palette<<f.read(1).ord}
anirat=f.read(1).ord
cycrat=f.read(1).ord
cm3cyc=[]; 8.times {cm3cyc<<f.read(1).ord}
aniflg=f.read(1).ord[7]!=0
cycflg=f.read(1).ord[7]!=0
debug "palette=#{$palette.inspect}"
debug "cm3cyc=#{cm3cyc.inspect} cycrat=#{cycrat} cycflg=#{cycflg} anirat=#{anirat} aniflg=#{aniflg}"
f.read(243) if not sans_motifs
linbuf=Array.new(160,0); buff1=Array.new(20,0); buff2=Array.new(20,0)
puts "P6\n#{cols} #{rows}\n255\n"
(pictyp[7]+1).times {
lines=f.read(1).ord
lines.times {
u=0; y=0; bitu=7; bity=7; x=0; a=nil
contr=f.read(1).ord
if contr<128
20 .times {|i| buff1[i]=f.read(1).ord }
contr.times {|i| buff2[i]=f.read(1).ord }
end
160.times {
if contr>=128; a = f.read(1).ord
else
cc=buff1[u][bitu]; bitu-=1; if bitu<0; bitu=7; u+=1 end
if cc==0; a=linbuf[(x-1)%160]
else
cc=buff2[y][bity]; bity-=1; if bity<0; bity=7; y+=1 end
if cc==0; a=linbuf[x] else a=f.read(1).ord end
end
end
linbuf[x]=a; dump a>>4; dump a&15; x+=1
}
}
}
extra=0; extra+=1 while f.read(1); debug "#{extra} octets de trop" if extra>0
-----------------8<--------découpez-ici--------8<-----------------
______________________________________________________________________
| Mathieu BOUCHARD --- tél: 514.623.3801, 514.383.3801 --- Montréal, QC
More information about the Coco
mailing list