mirror of https://bitbucket.org/ausocean/av.git
codec/mjpeg: removed putBuffer and its usage
This commit is contained in:
parent
ab2f2e4c0b
commit
ef4e9a3f69
|
@ -253,9 +253,7 @@ func (c *Context) ParsePayload(p []byte, m bool) error {
|
|||
|
||||
c.blen = 0
|
||||
|
||||
putBuf := newPutBuffer(c.buf[c.blen:])
|
||||
writeHeader(putBuf, int(t), int(width), int(height), qLen/64, dri, qTable)
|
||||
c.blen += putBuf.len
|
||||
c.blen += writeHeader(c.buf[c.blen:], int(t), int(width), int(height), qLen/64, dri, qTable)
|
||||
}
|
||||
|
||||
if c.blen == 0 {
|
||||
|
@ -295,55 +293,73 @@ func get24(p []byte) int {
|
|||
}
|
||||
|
||||
// writeHeader writes a JPEG header to the writer w.
|
||||
func writeHeader(p *putBuffer, _type, width, height, nbqTab, dri int, qtable []byte) {
|
||||
func writeHeader(p []byte, _type, width, height, nbqTab, dri int, qtable []byte) int {
|
||||
width <<= 3
|
||||
height <<= 3
|
||||
|
||||
// Indicate start of image.
|
||||
p.put16(0xff00 | codeSOI)
|
||||
idx := 0
|
||||
binary.BigEndian.PutUint16(p[idx:], 0xff00|codeSOI)
|
||||
idx += 2
|
||||
|
||||
// Write JFIF header.
|
||||
p.put16(0xff00 | codeAPP0)
|
||||
p.put16(jfifHeadLen)
|
||||
p.putBytes([]byte(jfifLabel))
|
||||
p.put16(jfifVer)
|
||||
p.put8(jfifDensityUnit)
|
||||
p.put16(jfifXDensity)
|
||||
p.put16(jfifYDensity)
|
||||
p.put8(jfifXThumbCnt)
|
||||
p.put8(jfifYThumbCnt)
|
||||
binary.BigEndian.PutUint16(p[idx:], 0xff00|codeAPP0)
|
||||
binary.BigEndian.PutUint16(p[idx+2:], jfifHeadLen)
|
||||
idx += 4
|
||||
|
||||
src := []byte(jfifLabel)
|
||||
copy(p[idx:], src)
|
||||
idx += len(src)
|
||||
|
||||
binary.BigEndian.PutUint16(p[idx:], jfifVer)
|
||||
p[idx+2] = jfifDensityUnit
|
||||
binary.BigEndian.PutUint16(p[idx+3:], jfifXDensity)
|
||||
binary.BigEndian.PutUint16(p[idx+5:], jfifYDensity)
|
||||
p[idx+7] = jfifXThumbCnt
|
||||
p[idx+8] = jfifYThumbCnt
|
||||
idx += 9
|
||||
|
||||
// If we want to define restart interval then write that.
|
||||
if dri != 0 {
|
||||
p.put16(0xff00 | codeDRI)
|
||||
p.put16(4)
|
||||
p.put16(uint16(dri))
|
||||
binary.BigEndian.PutUint16(p[idx:], 0xff00|codeDRI)
|
||||
binary.BigEndian.PutUint16(p[idx+2:], 4)
|
||||
binary.BigEndian.PutUint16(p[idx+4:], uint16(dri))
|
||||
idx += 6
|
||||
}
|
||||
|
||||
// Define quantization tables.
|
||||
p.put16(0xff00 | codeDQT)
|
||||
binary.BigEndian.PutUint16(p[idx:], 0xff00|codeDQT)
|
||||
idx += 2
|
||||
|
||||
// Calculate table size and create slice for table.
|
||||
ts := 2 + nbqTab*(1+64)
|
||||
p.put16(uint16(ts))
|
||||
binary.BigEndian.PutUint16(p[idx:], uint16(ts))
|
||||
idx += 2
|
||||
|
||||
for i := 0; i < nbqTab; i++ {
|
||||
p.put8(uint8(i))
|
||||
p.putBytes(qtable[64*i : (64*i)+64])
|
||||
p[idx] = byte(i)
|
||||
idx++
|
||||
|
||||
src := qtable[64*i : (64*i)+64]
|
||||
copy(p[idx:], src)
|
||||
idx += len(src)
|
||||
}
|
||||
|
||||
// Define huffman table.
|
||||
p.put16(0xff00 | codeDHT)
|
||||
lenIdx := p.len
|
||||
p.put16(0)
|
||||
writeHuffman(p, 0, 0, bitsDCLum, valDC)
|
||||
writeHuffman(p, 0, 1, bitsDCChr, valDC)
|
||||
writeHuffman(p, 1, 0, bitsACLum, valACLum)
|
||||
writeHuffman(p, 1, 1, bitsACChr, valACChr)
|
||||
p.put16At(uint16(p.len-lenIdx), lenIdx)
|
||||
binary.BigEndian.PutUint16(p[idx:], 0xff00|codeDHT)
|
||||
idx += 2
|
||||
lenIdx := idx
|
||||
binary.BigEndian.PutUint16(p[idx:], 0)
|
||||
idx += 2
|
||||
idx += writeHuffman(p[idx:], 0, 0, bitsDCLum, valDC)
|
||||
idx += writeHuffman(p[idx:], 0, 1, bitsDCChr, valDC)
|
||||
idx += writeHuffman(p[idx:], 1, 0, bitsACLum, valACLum)
|
||||
idx += writeHuffman(p[idx:], 1, 1, bitsACChr, valACChr)
|
||||
binary.BigEndian.PutUint16(p[lenIdx:], uint16(idx-lenIdx))
|
||||
|
||||
// Start of frame.
|
||||
p.put16(0xff00 | codeSOF0)
|
||||
binary.BigEndian.PutUint16(p[idx:], 0xff00|codeSOF0)
|
||||
idx += 2
|
||||
|
||||
// Derive sample type.
|
||||
sample := 1
|
||||
|
@ -357,51 +373,66 @@ func writeHeader(p *putBuffer, _type, width, height, nbqTab, dri int, qtable []b
|
|||
mtxNo = 1
|
||||
}
|
||||
|
||||
p.put16(sofLen)
|
||||
p.put8(sofPrecision)
|
||||
p.put16(uint16(height))
|
||||
p.put16(uint16(width))
|
||||
p.put8(sofNoOfComponents)
|
||||
binary.BigEndian.PutUint16(p[idx:], sofLen)
|
||||
p[idx+2] = byte(sofPrecision)
|
||||
binary.BigEndian.PutUint16(p[idx+3:], uint16(height))
|
||||
binary.BigEndian.PutUint16(p[idx+5:], uint16(width))
|
||||
p[idx+7] = byte(sofNoOfComponents)
|
||||
idx += 8
|
||||
|
||||
// TODO: find meaning of these fields.
|
||||
p.put8(1)
|
||||
p.put8(uint8((2 << 4) | sample))
|
||||
p.put8(0)
|
||||
p.put8(2)
|
||||
p.put8(1<<4 | 1)
|
||||
p.put8(uint8(mtxNo))
|
||||
p.put8(3)
|
||||
p.put8(1<<4 | 1)
|
||||
p.put8(uint8(mtxNo))
|
||||
p[idx] = 1
|
||||
p[idx+1] = uint8((2 << 4) | sample)
|
||||
p[idx+2] = 0
|
||||
p[idx+3] = 2
|
||||
p[idx+4] = 1<<4 | 1
|
||||
p[idx+5] = uint8(mtxNo)
|
||||
p[idx+6] = 3
|
||||
p[idx+7] = 1<<4 | 1
|
||||
p[idx+8] = uint8(mtxNo)
|
||||
idx += 9
|
||||
|
||||
// Write start of scan.
|
||||
p.put16(0xff00 | codeSOS)
|
||||
p.put16(sosLen)
|
||||
p.put8(sosComponentsInScan)
|
||||
binary.BigEndian.PutUint16(p[idx:], 0xff00|codeSOS)
|
||||
binary.BigEndian.PutUint16(p[idx+2:], sosLen)
|
||||
p[idx+4] = sosComponentsInScan
|
||||
idx += 5
|
||||
|
||||
// TODO: find out what remaining fields are.
|
||||
p.put8(1)
|
||||
p.put8(0)
|
||||
p.put8(2)
|
||||
p.put8(17)
|
||||
p.put8(3)
|
||||
p.put8(17)
|
||||
p.put8(0)
|
||||
p.put8(63)
|
||||
p.put8(0)
|
||||
p[idx] = 1
|
||||
p[idx+1] = 0
|
||||
p[idx+2] = 2
|
||||
p[idx+3] = 17
|
||||
p[idx+4] = 3
|
||||
p[idx+5] = 17
|
||||
p[idx+6] = 0
|
||||
p[idx+7] = 63
|
||||
p[idx+8] = 0
|
||||
idx += 9
|
||||
|
||||
return idx
|
||||
}
|
||||
|
||||
// writeHuffman write a JPEG huffman table to w.
|
||||
func writeHuffman(p *putBuffer, class, id int, bits, values []byte) {
|
||||
p.put8(uint8(class<<4 | id))
|
||||
func writeHuffman(p []byte, class, id int, bits, values []byte) int {
|
||||
idx := 0
|
||||
p[idx] = uint8(class<<4 | id)
|
||||
idx++
|
||||
|
||||
var n int
|
||||
for i := 1; i <= 16; i++ {
|
||||
n += int(bits[i])
|
||||
}
|
||||
|
||||
p.putBytes(bits[1:17])
|
||||
p.putBytes(values[0:n])
|
||||
src := bits[1:17]
|
||||
copy(p[idx:], src)
|
||||
idx += len(src)
|
||||
|
||||
src = values[0:n]
|
||||
copy(p[idx:], src)
|
||||
idx += len(src)
|
||||
|
||||
return idx
|
||||
}
|
||||
|
||||
// defaultQTable returns a default quantization table.
|
||||
|
|
|
@ -1,74 +0,0 @@
|
|||
/*
|
||||
DESCRIPTION
|
||||
utils.go provides buffer utilities used by jpeg.go.
|
||||
|
||||
TODO: make this exported in codecutil.
|
||||
|
||||
AUTHOR
|
||||
Saxon Nelson-Milton <saxon@ausocean.org>
|
||||
|
||||
LICENSE
|
||||
Copyright (C) 2019 the Australian Ocean Lab (AusOcean)
|
||||
|
||||
It is free software: you can redistribute it and/or modify them
|
||||
under the terms of the GNU General Public License as published by the
|
||||
Free Software Foundation, either version 3 of the License, or (at your
|
||||
option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with revid in gpl.txt. If not, see http://www.gnu.org/licenses.
|
||||
*/
|
||||
|
||||
package mjpeg
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"io"
|
||||
)
|
||||
|
||||
type putBuffer struct {
|
||||
len int
|
||||
bytes []byte
|
||||
}
|
||||
|
||||
func newPutBuffer(b []byte) *putBuffer { return &putBuffer{bytes: b} }
|
||||
|
||||
func (p *putBuffer) Write(b []byte) (int, error) {
|
||||
copy(p.bytes[p.len:], b)
|
||||
p.len += len(b)
|
||||
return len(b), nil
|
||||
}
|
||||
|
||||
func (p *putBuffer) writeTo(d io.Writer) (int, error) {
|
||||
n, err := d.Write(p.bytes[0:p.len])
|
||||
p.len -= n
|
||||
return n, err
|
||||
}
|
||||
|
||||
func (p *putBuffer) put16(v uint16) {
|
||||
binary.BigEndian.PutUint16(p.bytes[p.len:], v)
|
||||
p.len += 2
|
||||
}
|
||||
|
||||
func (p *putBuffer) put8(v uint8) {
|
||||
p.bytes[p.len] = byte(v)
|
||||
p.len++
|
||||
}
|
||||
|
||||
func (p *putBuffer) putBytes(src []byte) {
|
||||
copy(p.bytes[p.len:], src)
|
||||
p.len += len(src)
|
||||
}
|
||||
|
||||
func (p *putBuffer) put16At(v uint16, i int) {
|
||||
binary.BigEndian.PutUint16(p.bytes[i:], v)
|
||||
}
|
||||
|
||||
func (p *putBuffer) reset() {
|
||||
p.len = 0
|
||||
}
|
Loading…
Reference in New Issue