Last active
October 27, 2016 01:38
-
-
Save yoya/c2e87fe3227edad2dd228b75a9aef91d to your computer and use it in GitHub Desktop.
GIF one frame only sample.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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