Skip to content

Instantly share code, notes, and snippets.

@yoya
Last active October 27, 2016 01:38
Show Gist options
  • Save yoya/c2e87fe3227edad2dd228b75a9aef91d to your computer and use it in GitHub Desktop.
Save yoya/c2e87fe3227edad2dd228b75a9aef91d to your computer and use it in GitHub Desktop.
GIF one frame only sample.
// 2016/10/27 (c) yoya@awm.jp
// ref) https://github.com/yoya/IO_GIF/blob/master/IO/GIF.php
package main
import (
"fmt"
"io/ioutil"
"math"
"os"
)
func GIFOneFrameOnly(bytes []byte) int {
flags := bytes[10]
globalColorTableFlag := (flags & 0x80) >> 7
sizeOfGlobalColorTable := (flags & 0x07)
var offset = 13
if globalColorTableFlag != 0 {
colorTableSize := int(math.Pow(2, float64(sizeOfGlobalColorTable+1)))
offset += 3 * colorTableSize
}
for {
// fmt.Printf("# -- offset:%x\n", offset)
separator := bytes[offset]
offset++
switch separator {
case 0x3B: // Trailer
case 0x21: // Extention
extensionBlockLabel := bytes[offset]
extensionDataSize := bytes[offset+1]
offset += 2 + int(extensionDataSize)
if extensionBlockLabel == 0xff { // Application Extension
for {
subBlockSize := bytes[offset]
offset++
if subBlockSize == 0 {
break
}
offset += int(subBlockSize)
}
} else {
offset++ // extensionBlock Trailer
}
case 0x2C: // Image
flags := bytes[offset+8]
localColorTableFlag := (flags & 0x80) >> 7
sizeOfLocalColorTable := (flags & 0x07)
offset += 9
if localColorTableFlag != 0 {
colorTableSize := int(math.Pow(2, float64(sizeOfLocalColorTable+1)))
offset += 3 * colorTableSize
}
offset ++ // LZWMinimumCodeSize
for {
subBlockSize := bytes[offset]
offset++
if subBlockSize == 0 {
break
}
offset += int(subBlockSize)
}
bytes[offset] = 0x3B // trailer writing
default:
// nothing to do
}
if separator == 0x3B {
break
}
}
return offset
}
func main() {
var err error
if len(os.Args) < 3 {
fmt.Println("Usage: gifoneframeonly <input GIF> <output GIF>")
return
}
// data read
f, err := os.Open(os.Args[1])
if err != nil {
panic(err)
}
defer f.Close()
bytes, err := ioutil.ReadAll(f)
if err != nil {
panic(err)
}
len := GIFOneFrameOnly(bytes)
ioutil.WriteFile(os.Args[2], bytes[0:len], 0755)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment