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 c.blen = 0
putBuf := newPutBuffer(c.buf[c.blen:]) c.blen += writeHeader(c.buf[c.blen:], int(t), int(width), int(height), qLen/64, dri, qTable)
writeHeader(putBuf, int(t), int(width), int(height), qLen/64, dri, qTable)
c.blen += putBuf.len
} }
if c.blen == 0 { if c.blen == 0 {
@ -295,55 +293,73 @@ func get24(p []byte) int {
} }
// writeHeader writes a JPEG header to the writer w. // 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 width <<= 3
height <<= 3 height <<= 3
// Indicate start of image. // Indicate start of image.
p.put16(0xff00 | codeSOI) idx := 0
binary.BigEndian.PutUint16(p[idx:], 0xff00|codeSOI)
idx += 2
// Write JFIF header. // Write JFIF header.
p.put16(0xff00 | codeAPP0) binary.BigEndian.PutUint16(p[idx:], 0xff00|codeAPP0)
p.put16(jfifHeadLen) binary.BigEndian.PutUint16(p[idx+2:], jfifHeadLen)
p.putBytes([]byte(jfifLabel)) idx += 4
p.put16(jfifVer)
p.put8(jfifDensityUnit) src := []byte(jfifLabel)
p.put16(jfifXDensity) copy(p[idx:], src)
p.put16(jfifYDensity) idx += len(src)
p.put8(jfifXThumbCnt)
p.put8(jfifYThumbCnt) 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 we want to define restart interval then write that.
if dri != 0 { if dri != 0 {
p.put16(0xff00 | codeDRI) binary.BigEndian.PutUint16(p[idx:], 0xff00|codeDRI)
p.put16(4) binary.BigEndian.PutUint16(p[idx+2:], 4)
p.put16(uint16(dri)) binary.BigEndian.PutUint16(p[idx+4:], uint16(dri))
idx += 6
} }
// Define quantization tables. // Define quantization tables.
p.put16(0xff00 | codeDQT) binary.BigEndian.PutUint16(p[idx:], 0xff00|codeDQT)
idx += 2
// Calculate table size and create slice for table. // Calculate table size and create slice for table.
ts := 2 + nbqTab*(1+64) ts := 2 + nbqTab*(1+64)
p.put16(uint16(ts)) binary.BigEndian.PutUint16(p[idx:], uint16(ts))
idx += 2
for i := 0; i < nbqTab; i++ { for i := 0; i < nbqTab; i++ {
p.put8(uint8(i)) p[idx] = byte(i)
p.putBytes(qtable[64*i : (64*i)+64]) idx++
src := qtable[64*i : (64*i)+64]
copy(p[idx:], src)
idx += len(src)
} }
// Define huffman table. // Define huffman table.
p.put16(0xff00 | codeDHT) binary.BigEndian.PutUint16(p[idx:], 0xff00|codeDHT)
lenIdx := p.len idx += 2
p.put16(0) lenIdx := idx
writeHuffman(p, 0, 0, bitsDCLum, valDC) binary.BigEndian.PutUint16(p[idx:], 0)
writeHuffman(p, 0, 1, bitsDCChr, valDC) idx += 2
writeHuffman(p, 1, 0, bitsACLum, valACLum) idx += writeHuffman(p[idx:], 0, 0, bitsDCLum, valDC)
writeHuffman(p, 1, 1, bitsACChr, valACChr) idx += writeHuffman(p[idx:], 0, 1, bitsDCChr, valDC)
p.put16At(uint16(p.len-lenIdx), lenIdx) 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. // Start of frame.
p.put16(0xff00 | codeSOF0) binary.BigEndian.PutUint16(p[idx:], 0xff00|codeSOF0)
idx += 2
// Derive sample type. // Derive sample type.
sample := 1 sample := 1
@ -357,51 +373,66 @@ func writeHeader(p *putBuffer, _type, width, height, nbqTab, dri int, qtable []b
mtxNo = 1 mtxNo = 1
} }
p.put16(sofLen) binary.BigEndian.PutUint16(p[idx:], sofLen)
p.put8(sofPrecision) p[idx+2] = byte(sofPrecision)
p.put16(uint16(height)) binary.BigEndian.PutUint16(p[idx+3:], uint16(height))
p.put16(uint16(width)) binary.BigEndian.PutUint16(p[idx+5:], uint16(width))
p.put8(sofNoOfComponents) p[idx+7] = byte(sofNoOfComponents)
idx += 8
// TODO: find meaning of these fields. // TODO: find meaning of these fields.
p.put8(1) p[idx] = 1
p.put8(uint8((2 << 4) | sample)) p[idx+1] = uint8((2 << 4) | sample)
p.put8(0) p[idx+2] = 0
p.put8(2) p[idx+3] = 2
p.put8(1<<4 | 1) p[idx+4] = 1<<4 | 1
p.put8(uint8(mtxNo)) p[idx+5] = uint8(mtxNo)
p.put8(3) p[idx+6] = 3
p.put8(1<<4 | 1) p[idx+7] = 1<<4 | 1
p.put8(uint8(mtxNo)) p[idx+8] = uint8(mtxNo)
idx += 9
// Write start of scan. // Write start of scan.
p.put16(0xff00 | codeSOS) binary.BigEndian.PutUint16(p[idx:], 0xff00|codeSOS)
p.put16(sosLen) binary.BigEndian.PutUint16(p[idx+2:], sosLen)
p.put8(sosComponentsInScan) p[idx+4] = sosComponentsInScan
idx += 5
// TODO: find out what remaining fields are. // TODO: find out what remaining fields are.
p.put8(1) p[idx] = 1
p.put8(0) p[idx+1] = 0
p.put8(2) p[idx+2] = 2
p.put8(17) p[idx+3] = 17
p.put8(3) p[idx+4] = 3
p.put8(17) p[idx+5] = 17
p.put8(0) p[idx+6] = 0
p.put8(63) p[idx+7] = 63
p.put8(0) p[idx+8] = 0
idx += 9
return idx
} }
// writeHuffman write a JPEG huffman table to w. // writeHuffman write a JPEG huffman table to w.
func writeHuffman(p *putBuffer, class, id int, bits, values []byte) { func writeHuffman(p []byte, class, id int, bits, values []byte) int {
p.put8(uint8(class<<4 | id)) idx := 0
p[idx] = uint8(class<<4 | id)
idx++
var n int var n int
for i := 1; i <= 16; i++ { for i := 1; i <= 16; i++ {
n += int(bits[i]) n += int(bits[i])
} }
p.putBytes(bits[1:17]) src := bits[1:17]
p.putBytes(values[0:n]) 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. // 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
}