Refactor bitsmash into its own package
-package main
-
-import (
- "errors"
- "fmt"
- "image"
- "image/draw"
- "io"
- "math"
- "log"
- "os"
- "sort"
-
- _ "image/png"
-
- "bytex64.net/code/bitsmash/packet"
- "bytex64.net/code/bitsmash/palette"
- "bytex64.net/code/bitsmash/ac"
-)
-
-type scanFunc func(pixels []uint8) packet.Packet
-
-var scanFuncs []scanFunc = []scanFunc {
- packet.ScanRLE,
- packet.ScanBinaryPattern,
- packet.ScanDirect,
-}
-
-var sizes []int = []int{
- 8,
- 16,
- 24,
- 32,
- 48,
- 64,
- 96,
- 128,
-}
-
-func validSize(s int) bool {
- for _, n := range(sizes) {
- if n == s {
- return true
- }
- }
- return false
-}
-
-func sizeIndex(s int) int {
- for i, n := range(sizes) {
- if n == s {
- return i
- }
- }
- return -1
-}
-
-type EncodeOpts struct {
- optimize int
- palette int
-}
-
-type BitSmash struct {
- size int
- palette int
- transparent bool
- packetList []packet.Packet
-}
-
-func findPalette(img image.Image) int {
- selected := 0
- minimum_error := float64(1e99)
- size := img.Bounds().Size()
-
- for i, p := range(palette.Palettes) {
- error := float64(0)
- for y := 0; y < size.Y; y++ {
- for x := 0; x < size.X; x++ {
- pixel_color := img.At(x, y)
- _, _, _, a := pixel_color.RGBA()
- if a < 0x7FFF {
- // Don't calculate transparent pixels
- continue
- }
- palette_color := p.Convert(pixel_color)
- error += palette_color.(palette.RGB8).Distance(pixel_color)
- }
- }
- log.Printf("Palette %d error %f\n", i, error);
- if error < minimum_error {
- selected = i
- minimum_error = error
- }
- }
-
- return selected
-}
-
-func loadImage(filename string, opts *EncodeOpts) image.PalettedImage {
- reader, err := os.Open(filename)
- if err != nil {
- log.Fatal(err)
- }
- defer reader.Close()
-
- img, _, err := image.Decode(reader)
- if err != nil {
- log.Fatal(err)
- }
-
- size := img.Bounds().Size()
- if size.X > 128 {
- log.Fatal("Image width must be less than 128 pixels")
- }
-
- // Pad the width to one of our valid sizes
- if !validSize(size.X) {
- var newWidth int
- for _, s := range(sizes) {
- if size.X < s {
- newWidth = s
- break
- }
- }
- log.Printf("Padding image width %d to %d pixels", size.X, newWidth)
- r := image.Rect(0, 0, newWidth, size.Y)
- newImage := image.NewRGBA(r)
- draw.Draw(newImage, r, image.Transparent, image.ZP, draw.Src)
- draw.Draw(newImage, img.Bounds(), img, image.ZP, draw.Src)
- img = newImage
- }
-
- // If no palette has been specified, automatically select one
- if (opts.palette == -1) {
- opts.palette = findPalette(img)
- }
- log.Printf("Using palette %d\n", opts.palette);
-
- // Convert to the selected palette
- pImage := image.NewPaletted(img.Bounds(), palette.Palettes[opts.palette])
- draw.Draw(pImage, img.Bounds(), img, image.ZP, draw.Src)
-
- return pImage
-}
-
-func findAllEncodeLengths(pixels []uint8, steps int) []packet.PacketRun {
- results := make([]packet.PacketRun, 0)
- if len(pixels) == 0 {
- return results
- }
-
- for _, scan := range(scanFuncs) {
- pkt := scan(pixels)
- if pkt == nil {
- continue
- }
- pkt_length := pkt.Length()
- pkt_bytes := pkt.ByteLength()
- if steps > 1 && len(pixels) > pkt_length {
- rec_results := findAllEncodeLengths(pixels[pkt_length:], steps - 1)
- for _, r := range(rec_results) {
- results = append(results, packet.PacketRun{r.Length + pkt_length, r.Bytes + pkt_bytes, r.Depth + 1, pkt})
- }
- } else {
- results = append(results, packet.PacketRun{pkt_length, pkt_bytes, 1, pkt})
- }
- }
-
- return results
-}
-
-func findOptimalEncoding(pixels []uint8, optimize int) packet.Packet {
- results := findAllEncodeLengths(pixels, optimize)
- sort.Sort(packet.ByPacketEfficiency(results))
- /*
- fmt.Printf("optimal encodings (%d bytes remain):\n", len(pixels))
- for _, v := range(results) {
- fmt.Println(v)
- }
- */
- return results[0].Head
-}
-
-func findRepeats(packetlist []packet.Packet) []packet.Packet {
- outlist := make([]packet.Packet, 1, len(packetlist))
- outlist[0] = packetlist[0]
-
- for i := 1; i < len(packetlist); {
- pkt := packet.ScanRepeat(packetlist, i)
- if pkt != nil {
- outlist = append(outlist, pkt)
- rpkt := pkt.(*packet.RepeatPacket)
- i += rpkt.Count()
- } else {
- outlist = append(outlist, packetlist[i])
- i++
- continue
- }
- }
-
- return outlist
-}
-
-func (self *BitSmash) unpackRepeat() []packet.Packet {
- outlist := make([]packet.Packet, 1)
- outlist[0] = self.packetList[0]
-
- c := 1
- for _, p := range(self.packetList) {
- switch p.(type) {
- case *packet.RepeatPacket:
- rp := p.(*packet.RepeatPacket)
- outlist = rp.UnRepeat(outlist, c)
- c += rp.Count()
- default:
- outlist = append(outlist, p)
- c++
- }
- }
-
- return outlist
-}
-
-func getPixelList(img image.PalettedImage) []uint8 {
- p := img.(*image.Paletted)
-
- return p.Pix
-}
-
-func NewFromPixels(pixels []uint8, size int, opts *EncodeOpts) BitSmash {
- bs := BitSmash{
- size,
- opts.palette,
- false,
- make([]packet.Packet, 0, 1),
- }
-
- i := 0
- for i < len(pixels) {
- packet := findOptimalEncoding(pixels[i:], opts.optimize)
- i += packet.Length()
- bs.packetList = append(bs.packetList, packet)
- }
-
- bs.packetList = findRepeats(bs.packetList)
-
- return bs
-}
-
-func NewFromImage(filename string, opts *EncodeOpts) BitSmash {
- image := loadImage(filename, opts)
- size := image.Bounds().Size().X
- return NewFromPixels(getPixelList(image), size, opts)
-}
-
-func (self *BitSmash) Size() image.Point {
- return image.Point{self.size, self.Length() / self.size}
-}
-
-func (self *BitSmash) Length() int {
- n := 0
- for _, p := range(self.packetList) {
- n += p.Length()
- }
- return n
-}
-
-func (self *BitSmash) ByteLength() int {
- n_pd := int(math.Ceil(float64(len(self.packetList)) / 4.0))
- total_len := n_pd + 3
- for _, p := range(self.packetList) {
- total_len += p.ByteLength()
- }
- return total_len
-}
-
-func (self *BitSmash) packetType(n int) int {
- switch self.packetList[n].(type) {
- case *packet.RLEPacket:
- return 0
- case *packet.BinaryPatternPacket:
- return 1
- case *packet.DirectPacket:
- return 2
- case *packet.RepeatPacket:
- return 3
- }
- return -1
-}
-
-func NewFromBSFile(filename string) BitSmash {
- bs := BitSmash{
- 0,
- 0,
- false,
- nil,
- }
-
- file, err := os.Open(filename)
- defer file.Close()
- if err != nil {
- log.Fatalf("Failed to open: %v", err)
- }
- err = bs.ReadFrom(file)
- if err != nil {
- log.Fatalf("Reading file: %v", err)
- }
-
- return bs
-}
-
-func (self *BitSmash) codecManagerInit(c ac.CodecManager) {
- c.AddModel(packet.CONTEXT_PACKET_TYPE, ac.NewModelOrder0(4))
- c.AddModel(packet.CONTEXT_COLOR, ac.NewModelOrder0(16))
- c.AddModel(packet.CONTEXT_PATTERN_NUMBER, ac.NewModelOrder0PreBias(16, packet.ContextBias(packet.CONTEXT_PATTERN_NUMBER)))
- c.AddModel(packet.CONTEXT_PATTERN_REPEAT, ac.NewModelOrder0PreBias(8, packet.ContextBias(packet.CONTEXT_PATTERN_REPEAT)))
- c.AddModel(packet.CONTEXT_RLE_REPEAT, ac.NewModelOrder0(16))
- c.AddModel(packet.CONTEXT_REPEAT_DISTANCE, ac.NewModelOrder0PreBias(32, packet.ContextBias(packet.CONTEXT_REPEAT_DISTANCE)))
- c.AddModel(packet.CONTEXT_REPEAT_LENGTH, ac.NewModelOrder0PreBias(8, packet.ContextBias(packet.CONTEXT_REPEAT_LENGTH)))
-}
-
-func (self *BitSmash) ReadFrom(file io.Reader) error {
- var header [3]byte
- n, err := file.Read(header[:])
- if n < 3 {
- log.Fatal("Short read on header")
- } else if err != nil {
- return err
- }
- self.size = sizes[int(header[0]) & 0x7]
- self.palette = (int(header[0]) >> 3) & 0xF
- self.transparent = ((header[0] >> 7) & 0x1) == 1
-
- n_packets := int(header[1]) + (int(header[2]) & 0x3) + 1
- self.packetList = make([]packet.Packet, n_packets)
-
- decoder, err := ac.NewDecoder(file)
- if err != nil {
- return err
- }
- self.codecManagerInit(decoder)
-
- for i := 0; i < n_packets; i++ {
- var pkt packet.Packet // Packet! PACKET! PACKET!!!
- packet_type := decoder.Decode(packet.CONTEXT_PACKET_TYPE)
- switch packet_type {
- case 0:
- pkt = packet.DecodeRLE(decoder)
- case 1:
- pkt = packet.DecodeBinaryPattern(decoder)
- case 2:
- pkt = packet.DecodeDirect(decoder)
- case 3:
- pkt = packet.DecodeRepeat(decoder)
- }
- self.packetList[i] = pkt
- }
- return nil
-}
-
-func (self *BitSmash) WriteTo(file io.Writer) error {
- n_packets := len(self.packetList)
- if n_packets > 1024 {
- fmt.Println("Too many packets:", n_packets)
- return errors.New("Too many packets")
- }
-
- var header [3]byte
- transparent := 0
- if (self.transparent) {
- transparent = 1
- }
- header[0] = byte(sizeIndex(self.size) + (self.palette << 3) + (transparent << 7))
- header[1] = byte((n_packets - 1) & 0xFF)
- header[2] = byte(((n_packets - 1) >> 8) & 0x3)
-
- file.Write(header[:])
-
- encoder, err := ac.NewEncoder(file)
- if err != nil {
- return err
- }
- self.codecManagerInit(encoder)
-
- for i, p := range(self.packetList) {
- encoder.Encode(packet.CONTEXT_PACKET_TYPE, uint32(self.packetType(i)))
- p.Encode(encoder)
- }
- encoder.Finish()
-
- return nil
-}
-
-func (self *BitSmash) Dump() {
- self.unpackRepeat()
- size := self.Size()
- fmt.Printf("%d pixels, %dx%d\n", self.Length(), size.X, size.Y)
- fmt.Printf("%d packets:\n", len(self.packetList))
-
- c := 0
-
- for _, p := range(self.packetList) {
- switch p.(type) {
- case *packet.RepeatPacket:
- fmt.Printf(" %s\n", p)
- rp := p.(*packet.RepeatPacket)
- //d := c - rp.Distance()
- //tpl = rp.UnRepeat(tpl, c)
- for i := 0; i < rp.Count(); i++ {
- fmt.Printf("%-4d %s\n", c + i, rp.Slice()[i])
- }
- c += rp.Count()
- default:
- fmt.Printf("%-4d %s\n", c, p)
- c++
- }
- }
-
- fmt.Printf("%d total bytes\n", self.ByteLength())
-}
-
-func (self *BitSmash) RawDump() {
- for i, p := range(self.packetList) {
- fmt.Printf("%-4d %s\n", i, p)
- }
-}
+package bs
+
+import (
+ "bytex64.net/code/bitsmash/packet"
+ "bytex64.net/code/bitsmash/ac"
+)
+
+func (self *BitSmash) codecManagerInit(c ac.CodecManager) {
+ c.AddModel(packet.CONTEXT_PACKET_TYPE, ac.NewModelOrder0(4))
+ c.AddModel(packet.CONTEXT_COLOR, ac.NewModelOrder0(16))
+ c.AddModel(packet.CONTEXT_PATTERN_NUMBER, ac.NewModelOrder0PreBias(16, packet.ContextBias(packet.CONTEXT_PATTERN_NUMBER)))
+ c.AddModel(packet.CONTEXT_PATTERN_REPEAT, ac.NewModelOrder0PreBias(8, packet.ContextBias(packet.CONTEXT_PATTERN_REPEAT)))
+ c.AddModel(packet.CONTEXT_RLE_REPEAT, ac.NewModelOrder0(16))
+ c.AddModel(packet.CONTEXT_REPEAT_DISTANCE, ac.NewModelOrder0PreBias(32, packet.ContextBias(packet.CONTEXT_REPEAT_DISTANCE)))
+ c.AddModel(packet.CONTEXT_REPEAT_LENGTH, ac.NewModelOrder0PreBias(8, packet.ContextBias(packet.CONTEXT_REPEAT_LENGTH)))
+}
+package bs
+
+import (
+ "sort"
+
+ "bytex64.net/code/bitsmash/packet"
+)
+
+type scanFunc func(pixels []uint8) packet.Packet
+
+var scanFuncs []scanFunc = []scanFunc {
+ packet.ScanRLE,
+ packet.ScanBinaryPattern,
+ packet.ScanDirect,
+}
+
+func findAllEncodeLengths(pixels []uint8, steps int) []packet.PacketRun {
+ results := make([]packet.PacketRun, 0)
+ if len(pixels) == 0 {
+ return results
+ }
+
+ for _, scan := range(scanFuncs) {
+ pkt := scan(pixels)
+ if pkt == nil {
+ continue
+ }
+ pkt_length := pkt.Length()
+ pkt_bytes := pkt.ByteLength()
+ if steps > 1 && len(pixels) > pkt_length {
+ rec_results := findAllEncodeLengths(pixels[pkt_length:], steps - 1)
+ for _, r := range(rec_results) {
+ results = append(results, packet.PacketRun{r.Length + pkt_length, r.Bytes + pkt_bytes, r.Depth + 1, pkt})
+ }
+ } else {
+ results = append(results, packet.PacketRun{pkt_length, pkt_bytes, 1, pkt})
+ }
+ }
+
+ return results
+}
+
+func findOptimalEncoding(pixels []uint8, optimize int) packet.Packet {
+ results := findAllEncodeLengths(pixels, optimize)
+ sort.Sort(packet.ByPacketEfficiency(results))
+ /*
+ fmt.Printf("optimal encodings (%d bytes remain):\n", len(pixels))
+ for _, v := range(results) {
+ fmt.Println(v)
+ }
+ */
+ return results[0].Head
+}
+
+func findRepeats(packetlist []packet.Packet) []packet.Packet {
+ outlist := make([]packet.Packet, 1, len(packetlist))
+ outlist[0] = packetlist[0]
+
+ for i := 1; i < len(packetlist); {
+ pkt := packet.ScanRepeat(packetlist, i)
+ if pkt != nil {
+ outlist = append(outlist, pkt)
+ rpkt := pkt.(*packet.RepeatPacket)
+ i += rpkt.Count()
+ } else {
+ outlist = append(outlist, packetlist[i])
+ i++
+ continue
+ }
+ }
+
+ return outlist
+}
+package bs
+
+import (
+ "image"
+ "image/draw"
+ "log"
+ "os"
+
+ "bytex64.net/code/bitsmash/palette"
+)
+
+func loadImage(filename string, opts *EncodeOpts) image.PalettedImage {
+ reader, err := os.Open(filename)
+ if err != nil {
+ log.Fatal(err)
+ }
+ defer reader.Close()
+
+ img, _, err := image.Decode(reader)
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ size := img.Bounds().Size()
+ if size.X > 128 {
+ log.Fatal("Image width must be less than 128 pixels")
+ }
+
+ // Pad the width to one of our valid sizes
+ if !validSize(size.X) {
+ var newWidth int
+ for _, s := range(sizes) {
+ if size.X < s {
+ newWidth = s
+ break
+ }
+ }
+ log.Printf("Padding image width %d to %d pixels", size.X, newWidth)
+ r := image.Rect(0, 0, newWidth, size.Y)
+ newImage := image.NewRGBA(r)
+ draw.Draw(newImage, r, image.Transparent, image.ZP, draw.Src)
+ draw.Draw(newImage, img.Bounds(), img, image.ZP, draw.Src)
+ img = newImage
+ }
+
+ // If no palette has been specified, automatically select one
+ if (opts.Palette == -1) {
+ opts.Palette = findPalette(img)
+ log.Printf("Automatically selected palette %d\n", opts.Palette);
+ }
+
+ // Convert to the selected palette
+ pImage := image.NewPaletted(img.Bounds(), palette.Palettes[opts.Palette])
+ draw.Draw(pImage, img.Bounds(), img, image.ZP, draw.Src)
+
+ return pImage
+}
+
+func getPixelList(img image.PalettedImage) []uint8 {
+ p := img.(*image.Paletted)
+
+ return p.Pix
+}
+package bs
+
+import (
+ "io"
+ "log"
+ "fmt"
+ "errors"
+
+ "bytex64.net/code/bitsmash/packet"
+ "bytex64.net/code/bitsmash/ac"
+)
+
+func (self *BitSmash) packetType(n int) int {
+ switch self.packetList[n].(type) {
+ case *packet.RLEPacket:
+ return 0
+ case *packet.BinaryPatternPacket:
+ return 1
+ case *packet.DirectPacket:
+ return 2
+ case *packet.RepeatPacket:
+ return 3
+ }
+ return -1
+}
+
+func (self *BitSmash) ReadFrom(file io.Reader) error {
+ var header [3]byte
+ n, err := file.Read(header[:])
+ if n < 3 {
+ log.Fatal("Short read on header")
+ } else if err != nil {
+ return err
+ }
+ self.size = sizes[int(header[0]) & 0x7]
+ self.palette = (int(header[0]) >> 3) & 0xF
+ self.transparent = ((header[0] >> 7) & 0x1) == 1
+
+ n_packets := int(header[1]) + (int(header[2]) & 0x3) + 1
+ self.packetList = make([]packet.Packet, n_packets)
+
+ decoder, err := ac.NewDecoder(file)
+ if err != nil {
+ return err
+ }
+ self.codecManagerInit(decoder)
+
+ for i := 0; i < n_packets; i++ {
+ var pkt packet.Packet // Packet! PACKET! PACKET!!!
+ packet_type := decoder.Decode(packet.CONTEXT_PACKET_TYPE)
+ switch packet_type {
+ case 0:
+ pkt = packet.DecodeRLE(decoder)
+ case 1:
+ pkt = packet.DecodeBinaryPattern(decoder)
+ case 2:
+ pkt = packet.DecodeDirect(decoder)
+ case 3:
+ pkt = packet.DecodeRepeat(decoder)
+ }
+ self.packetList[i] = pkt
+ }
+ return nil
+}
+
+func (self *BitSmash) WriteTo(file io.Writer) error {
+ n_packets := len(self.packetList)
+ if n_packets > 1024 {
+ fmt.Println("Too many packets:", n_packets)
+ return errors.New("Too many packets")
+ }
+
+ var header [3]byte
+ transparent := 0
+ if (self.transparent) {
+ transparent = 1
+ }
+ header[0] = byte(sizeIndex(self.size) + (self.palette << 3) + (transparent << 7))
+ header[1] = byte((n_packets - 1) & 0xFF)
+ header[2] = byte(((n_packets - 1) >> 8) & 0x3)
+
+ file.Write(header[:])
+
+ encoder, err := ac.NewEncoder(file)
+ if err != nil {
+ return err
+ }
+ self.codecManagerInit(encoder)
+
+ for i, p := range(self.packetList) {
+ encoder.Encode(packet.CONTEXT_PACKET_TYPE, uint32(self.packetType(i)))
+ p.Encode(encoder)
+ }
+ encoder.Finish()
+
+ return nil
+}
+
+package bs
+
+import (
+ "log"
+ "os"
+
+ _ "image/png"
+
+ "bytex64.net/code/bitsmash/packet"
+)
+
+type EncodeOpts struct {
+ Optimize int
+ Palette int
+}
+
+type BitSmash struct {
+ size int
+ palette int
+ transparent bool
+ packetList []packet.Packet
+}
+
+func NewFromPixels(pixels []uint8, size int, opts *EncodeOpts) BitSmash {
+ bs := BitSmash{
+ size,
+ opts.Palette,
+ false,
+ make([]packet.Packet, 0, 1),
+ }
+
+ i := 0
+ for i < len(pixels) {
+ packet := findOptimalEncoding(pixels[i:], opts.Optimize)
+ i += packet.Length()
+ bs.packetList = append(bs.packetList, packet)
+ }
+
+ bs.packetList = findRepeats(bs.packetList)
+
+ return bs
+}
+
+func NewFromImage(filename string, opts *EncodeOpts) BitSmash {
+ image := loadImage(filename, opts)
+ size := image.Bounds().Size().X
+ return NewFromPixels(getPixelList(image), size, opts)
+}
+
+func NewFromFile(filename string) BitSmash {
+ bs := BitSmash{
+ 0,
+ 0,
+ false,
+ nil,
+ }
+
+ file, err := os.Open(filename)
+ defer file.Close()
+ if err != nil {
+ log.Fatalf("Failed to open: %v", err)
+ }
+ err = bs.ReadFrom(file)
+ if err != nil {
+ log.Fatalf("Reading file: %v", err)
+ }
+
+ return bs
+}
+package bs
+
+import (
+ "image"
+
+ "bytex64.net/code/bitsmash/palette"
+)
+
+func findPalette(img image.Image) int {
+ selected := 0
+ minimum_error := float64(1e99)
+ size := img.Bounds().Size()
+
+ for i, p := range(palette.Palettes) {
+ error := float64(0)
+ for y := 0; y < size.Y; y++ {
+ for x := 0; x < size.X; x++ {
+ pixel_color := img.At(x, y)
+ _, _, _, a := pixel_color.RGBA()
+ if a < 0x7FFF {
+ // Don't calculate transparent pixels
+ continue
+ }
+ palette_color := p.Convert(pixel_color)
+ error += palette_color.(palette.RGB8).Distance(pixel_color)
+ }
+ }
+ if error < minimum_error {
+ selected = i
+ minimum_error = error
+ }
+ }
+
+ return selected
+}
+package bs
+
+var sizes []int = []int{
+ 8,
+ 16,
+ 24,
+ 32,
+ 48,
+ 64,
+ 96,
+ 128,
+}
+
+func validSize(s int) bool {
+ for _, n := range(sizes) {
+ if n == s {
+ return true
+ }
+ }
+ return false
+}
+
+func sizeIndex(s int) int {
+ for i, n := range(sizes) {
+ if n == s {
+ return i
+ }
+ }
+ return -1
+}
+package bs
+
+import (
+ "fmt"
+ "image"
+ "math"
+
+ "bytex64.net/code/bitsmash/packet"
+)
+
+func (self *BitSmash) Size() image.Point {
+ return image.Point{self.size, self.Length() / self.size}
+}
+
+func (self *BitSmash) Length() int {
+ n := 0
+ for _, p := range(self.packetList) {
+ n += p.Length()
+ }
+ return n
+}
+
+func (self *BitSmash) ByteLength() int {
+ n_pd := int(math.Ceil(float64(len(self.packetList)) / 4.0))
+ total_len := n_pd + 3
+ for _, p := range(self.packetList) {
+ total_len += p.ByteLength()
+ }
+ return total_len
+}
+
+func (self *BitSmash) unpackRepeat() []packet.Packet {
+ outlist := make([]packet.Packet, 1)
+ outlist[0] = self.packetList[0]
+
+ c := 1
+ for _, p := range(self.packetList) {
+ switch p.(type) {
+ case *packet.RepeatPacket:
+ rp := p.(*packet.RepeatPacket)
+ outlist = rp.UnRepeat(outlist, c)
+ c += rp.Count()
+ default:
+ outlist = append(outlist, p)
+ c++
+ }
+ }
+
+ return outlist
+}
+
+func (self *BitSmash) Dump() {
+ self.unpackRepeat()
+ size := self.Size()
+ fmt.Printf("%d pixels, %dx%d\n", self.Length(), size.X, size.Y)
+ fmt.Printf("%d packets:\n", len(self.packetList))
+
+ c := 0
+
+ for _, p := range(self.packetList) {
+ switch p.(type) {
+ case *packet.RepeatPacket:
+ fmt.Printf(" %s\n", p)
+ rp := p.(*packet.RepeatPacket)
+ //d := c - rp.Distance()
+ //tpl = rp.UnRepeat(tpl, c)
+ for i := 0; i < rp.Count(); i++ {
+ fmt.Printf("%-4d %s\n", c + i, rp.Slice()[i])
+ }
+ c += rp.Count()
+ default:
+ fmt.Printf("%-4d %s\n", c, p)
+ c++
+ }
+ }
+
+ fmt.Printf("%d total bytes\n", self.ByteLength())
+}
+
+func (self *BitSmash) RawDump() {
+ for i, p := range(self.packetList) {
+ fmt.Printf("%-4d %s\n", i, p)
+ }
+}
"fmt"
"flag"
"encoding/base64"
+
+ "bytex64.net/code/bitsmash/bs"
)
type BitsmashOpts struct {
dump bool
base64 bool
files []string
- encodeOpts EncodeOpts
+ encodeOpts bs.EncodeOpts
}
func parseArgs() BitsmashOpts {
bo := BitsmashOpts{}
- bo.encodeOpts = EncodeOpts{}
+ bo.encodeOpts = bs.EncodeOpts{}
flag.BoolVar(&bo.decode, "decode", false, "Decode from bitsmash input rather than encode image")
flag.BoolVar(&bo.dump, "dump", false, "dump detailed information about encoding")
flag.BoolVar(&bo.base64, "base64", false, "Encode the result with base64")
- flag.IntVar(&bo.encodeOpts.optimize, "o", 3, "Optimization level")
- flag.IntVar(&bo.encodeOpts.palette, "p", -1, "Force palette N")
+ flag.IntVar(&bo.encodeOpts.Optimize, "o", 3, "Optimization level")
+ flag.IntVar(&bo.encodeOpts.Palette, "p", -1, "Force palette N")
flag.Parse()
bo.files = flag.Args()
return bo
os.Exit(1)
}
- var smash BitSmash
+ var smash bs.BitSmash
if (args.decode) {
- smash = NewFromBSFile(args.files[0])
+ smash = bs.NewFromFile(args.files[0])
} else {
- smash = NewFromImage(args.files[0], &args.encodeOpts)
+ smash = bs.NewFromImage(args.files[0], &args.encodeOpts)
}
if args.dump {