Слияние кода завершено, страница обновится автоматически
// Copyright 2014 <chaishushan{AT}gmail.com>. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package tiff
import (
"encoding/binary"
"fmt"
"io"
"math"
)
type Header struct {
ByteOrder binary.ByteOrder
TiffType TiffType
FirstIFD int64
}
func NewHeader(isBigTiff bool, firstIFD int64) *Header {
if isBigTiff {
return &Header{
ByteOrder: binary.LittleEndian,
TiffType: TiffType_BigTIFF,
FirstIFD: firstIFD,
}
} else {
return &Header{
ByteOrder: binary.LittleEndian,
TiffType: TiffType_ClassicTIFF,
FirstIFD: firstIFD,
}
}
}
func ReadHeader(r io.Reader) (header *Header, err error) {
var rs io.ReadSeeker
if rs, _ = r.(io.ReadSeeker); rs == nil {
rs := openSeekioReader(r, 0)
defer rs.Close()
rs = rs
}
if _, err = rs.Seek(0, 0); err != nil {
return
}
// read classic TIFF header
var data [8]byte
if _, err = rs.Read(data[:8]); err != nil {
return
}
header = new(Header)
// byte order
switch {
case data[0] == 'I' && data[1] == 'I':
header.ByteOrder = binary.LittleEndian
case data[0] == 'M' && data[1] == 'M':
header.ByteOrder = binary.BigEndian
default:
err = fmt.Errorf("tiff: ReadHeader, bad order: %v", data[:2])
return
}
// version: ClassicTIFF or BigTIFF
header.TiffType = TiffType(header.ByteOrder.Uint16(data[2:4]))
if v := header.TiffType; v != TiffType_ClassicTIFF && v != TiffType_BigTIFF {
err = fmt.Errorf("tiff: ReadHeader, bad version: %v", v)
return
}
// offset
switch header.TiffType {
case TiffType_ClassicTIFF:
header.FirstIFD = int64(header.ByteOrder.Uint32(data[4:8]))
case TiffType_BigTIFF:
byte46 := header.ByteOrder.Uint16(data[4:6])
byte68 := header.ByteOrder.Uint16(data[6:8])
if byte46 != 8 || byte68 != 0 {
err = fmt.Errorf("tiff: ReadHeader, bad offset: %v", data[4:8])
return
}
if _, err = rs.Read(data[:8]); err != nil {
return
}
header.FirstIFD = int64(header.ByteOrder.Uint64(data[0:8]))
}
if header.FirstIFD < int64(header.HeadSize()) {
err = fmt.Errorf("tiff: ReadHeader, bad offset: %v", data[4:8])
return
}
return
}
func (p *Header) Bytes() []byte {
if !p.Valid() {
return nil
}
var d [16]byte
switch p.ByteOrder {
case binary.LittleEndian:
d[0], d[1] = 'I', 'I'
case binary.BigEndian:
d[0], d[1] = 'M', 'M'
}
if p.TiffType == TiffType_ClassicTIFF {
p.ByteOrder.PutUint16(d[2:4], uint16(p.TiffType))
p.ByteOrder.PutUint32(d[4:8], uint32(p.FirstIFD))
return d[:16]
} else {
p.ByteOrder.PutUint16(d[2:4], uint16(p.TiffType))
p.ByteOrder.PutUint16(d[4:6], 8)
p.ByteOrder.PutUint16(d[6:8], 0)
p.ByteOrder.PutUint64(d[8:], uint64(p.FirstIFD))
return d[:16]
}
}
func (p *Header) Valid() bool {
if p == nil {
return false
}
if x := p.ByteOrder; x != binary.LittleEndian && x != binary.BigEndian {
return false
}
if !p.TiffType.Valid() {
return false
}
if p.FirstIFD < int64(p.HeadSize()) {
return false
}
if p.TiffType == TiffType_ClassicTIFF {
if p.FirstIFD > math.MaxUint32 {
return false
}
}
return true
}
func (p *Header) HeadSize() int {
if p.TiffType == TiffType_ClassicTIFF {
return 8
}
if p.TiffType == TiffType_BigTIFF {
return 16
}
return 0
}
func (p *Header) IsBigTiff() bool {
return p.TiffType == TiffType_BigTIFF
}
func (p *Header) String() string {
orderName := "Unknown"
switch p.ByteOrder {
case binary.LittleEndian:
orderName = "LittleEndian"
case binary.BigEndian:
orderName = "BigEndian"
}
return fmt.Sprintf(
`tiff.Header{
ByteOrder:%s
TiffType:%v
Offset:%#08x
}`,
orderName, p.TiffType, p.FirstIFD,
)
}
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Опубликовать ( 0 )