codec/mjpeg: removed putBuffer and its usage

This commit is contained in:
Saxon 2020-01-04 13:10:40 +10:30
parent ab2f2e4c0b
commit ef4e9a3f69
2 changed files with 91 additions and 134 deletions

View File

@ -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.

View File

@ -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
}