Skip to content

Commit

Permalink
RSDK-2077 Make sure custom depth type is big endian encoded (viamrobo…
Browse files Browse the repository at this point in the history
  • Loading branch information
bhaney authored and zaporter-work committed Mar 8, 2023
1 parent b4bbc5f commit 6605c78
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 31 deletions.
2 changes: 1 addition & 1 deletion .artifact/tree.json
Original file line number Diff line number Diff line change
Expand Up @@ -3881,7 +3881,7 @@
"size": 567
},
"fakeDM.vnd.viam.dep": {
"hash": "4a7dca803d353064c65886fae49c823a",
"hash": "80f3125fe6b7244ea0ca8ab7a27fa866",
"size": 424
},
"go_encoded_image.png": {
Expand Down
32 changes: 20 additions & 12 deletions rimage/depth_map_raw.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,11 @@ import (
const MagicNumIntVersionX = 6363110499870197078

// MagicNumIntViamType is the magic number (as an int) for the custom Viam depth type.
// magic number for ViamCustomType is uint64([]byte("DEPTHMAP")), Little Endian.
const MagicNumIntViamType = 5782988369567958340
// magic number for ViamCustomType is uint64([]byte("DEPTHMAP")), Big Endian.
const MagicNumIntViamType = 4919426490892632400

// MagicNumIntViamTypeLittleEndian is "PAMHTPED" for the ReadDepthMap function which uses LittleEndian to read.
const MagicNumIntViamTypeLittleEndian = 5782988369567958340

func _readNext(r io.Reader) (int64, error) {
data := make([]byte, 8)
Expand Down Expand Up @@ -63,7 +66,7 @@ func ReadDepthMap(r io.Reader) (*DepthMap, error) {
switch firstBytes {
case MagicNumIntVersionX: // magic number for VERSIONX
return readDepthMapVersionX(r)
case MagicNumIntViamType: // magic number for ViamCustomType is int64([]byte("DEPTHMAP"))
case MagicNumIntViamTypeLittleEndian: // magic number for ViamCustomType PAMHTPED (LittleEndian DEPTHMAP)
return readDepthMapViam(r)
default:
return readDepthMapRaw(r, firstBytes)
Expand All @@ -88,20 +91,25 @@ func readDepthMapRaw(ff io.Reader, firstBytes int64) (*DepthMap, error) {
func readDepthMapViam(ff io.Reader) (*DepthMap, error) {
f := bufio.NewReader(ff)
dm := &DepthMap{}
data := make([]byte, 8)

rawWidth, err := _readNext(f)
_, err := f.Read(data)
if err != nil {
return nil, errors.Wrapf(err, "could not read vnd.viam.dep width")
}
rawWidth := binary.BigEndian.Uint64(data)
dm.width = int(rawWidth)
rawHeight, err := _readNext(f)

_, err = f.Read(data)
if err != nil {
return nil, errors.Wrapf(err, "could not read vnd.viam.dep height")
}
rawHeight := binary.BigEndian.Uint64(data)
dm.height = int(rawHeight)

// dump the rest of the bytes in a depth slice
datSlice := make([]Depth, dm.height*dm.width)
err = binary.Read(f, binary.LittleEndian, &datSlice)
err = binary.Read(f, binary.BigEndian, &datSlice)
if err != nil {
return nil, errors.Wrapf(err, "could not read vnd.viam.dep data slice")
}
Expand Down Expand Up @@ -315,39 +323,39 @@ func WriteViamDepthMapTo(img image.Image, out io.Writer) (int64, error) {
width := img.Bounds().Dx()
height := img.Bounds().Dy()

binary.LittleEndian.PutUint64(buf, uint64(MagicNumIntViamType))
binary.BigEndian.PutUint64(buf, uint64(MagicNumIntViamType))
n, err := out.Write(buf)
totalN += int64(n)
if err != nil {
return totalN, err
}
binary.LittleEndian.PutUint64(buf, uint64(width))
binary.BigEndian.PutUint64(buf, uint64(width))
n, err = out.Write(buf)
totalN += int64(n)
if err != nil {
return totalN, err
}

binary.LittleEndian.PutUint64(buf, uint64(height))
binary.BigEndian.PutUint64(buf, uint64(height))
n, err = out.Write(buf)
totalN += int64(n)
if err != nil {
return totalN, err
}
switch dm := img.(type) {
case *DepthMap:
err = binary.Write(out, binary.LittleEndian, dm.data) // uint16 data
err = binary.Write(out, binary.BigEndian, dm.data)
if err != nil {
return totalN, err
}
totalN += int64(len(dm.data) * 2)
totalN += int64(len(dm.data) * 2) // uint16 data
case *image.Gray16:
grayBuf := make([]byte, 2)
for y := 0; y < height; y++ {
for x := 0; x < width; x++ {
i := dm.PixOffset(x, y)
z := uint16(dm.Pix[i+0])<<8 | uint16(dm.Pix[i+1])
binary.LittleEndian.PutUint16(grayBuf, z)
binary.BigEndian.PutUint16(grayBuf, z)
n, err = out.Write(grayBuf)
totalN += int64(n)
if err != nil {
Expand Down
5 changes: 0 additions & 5 deletions rimage/depth_map_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -374,7 +374,6 @@ func TestViamDepthMap(t *testing.T) {
func TestDepthMapEncoding(t *testing.T) {
m, err := NewDepthMapFromFile(context.Background(), artifact.MustPath("rimage/fakeDM.vnd.viam.dep"))
test.That(t, err, test.ShouldBeNil)

// Test values at points of DepthMap
// This example DepthMap (fakeDM) was made such that Depth(x,y) = x*y
test.That(t, m.Width(), test.ShouldEqual, 20)
Expand All @@ -385,10 +384,6 @@ func TestDepthMapEncoding(t *testing.T) {
test.That(t, testPt2, test.ShouldEqual, 60)

// Save DepthMap BYTES to a file
buf := bytes.Buffer{}
err = m.WriteToBuf(&buf)
test.That(t, err, test.ShouldBeNil)
test.That(t, buf.Bytes(), test.ShouldNotBeNil)
outDir := testutils.TempDirT(t, "", "rimage")
saveTo := outDir + "/grayboard_bytes.vnd.viam.dep"
err = WriteRawDepthMapToFile(m, saveTo)
Expand Down
20 changes: 7 additions & 13 deletions rimage/image_file.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package rimage

import (
"bufio"
"bytes"
"context"
"encoding/binary"
Expand Down Expand Up @@ -96,23 +95,18 @@ func init() {
},
func(r io.Reader) (image.Config, error) {
// Using Gray 16 as underlying color model for depth
f := r.(*bufio.Reader)
firstBytes, err := _readNext(r)
if err != nil || firstBytes != MagicNumIntViamType {
return image.Config{}, errors.Wrap(err, "first image bytes do not match expected magic number")
}
rawWidth, err := _readNext(f)
if err != nil {
return image.Config{}, err
}
rawHeight, err := _readNext(f)
imgBytes := make([]byte, RawDepthHeaderLength)
_, err := io.ReadFull(r, imgBytes)
if err != nil {
return image.Config{}, err
}
header := imgBytes[:RawDepthHeaderLength]
width := binary.BigEndian.Uint64(header[8:16])
height := binary.BigEndian.Uint64(header[16:24])
return image.Config{
ColorModel: color.Gray16Model,
Width: int(rawWidth),
Height: int(rawHeight),
Width: int(width),
Height: int(height),
}, nil
},
)
Expand Down
53 changes: 53 additions & 0 deletions rimage/image_file_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,22 @@ func TestRawRGBAEncodingDecoding(t *testing.T) {

encodedImgBytes, err := EncodeImage(context.Background(), img, utils.MimeTypeRawRGBA)
test.That(t, err, test.ShouldBeNil)
reader := bytes.NewReader(encodedImgBytes)

conf, header, err := image.DecodeConfig(reader)
test.That(t, err, test.ShouldBeNil)
test.That(t, header, test.ShouldEqual, "vnd.viam.rgba")
test.That(t, conf.Width, test.ShouldEqual, img.Bounds().Dx())
test.That(t, conf.Height, test.ShouldEqual, img.Bounds().Dy())

// decode with image package
reader = bytes.NewReader(encodedImgBytes)
imgDecoded, header, err := image.Decode(reader)
test.That(t, err, test.ShouldBeNil)
test.That(t, header, test.ShouldEqual, "vnd.viam.rgba")
test.That(t, imgDecoded.Bounds(), test.ShouldResemble, img.Bounds())
test.That(t, imgDecoded.At(3, 6), test.ShouldResemble, img.At(3, 6))
test.That(t, imgDecoded.At(1, 3), test.ShouldResemble, img.At(1, 3))

decodedImg, err := DecodeImage(context.Background(), encodedImgBytes, utils.MimeTypeRawRGBA)
test.That(t, err, test.ShouldBeNil)
Expand All @@ -96,3 +112,40 @@ func TestRawRGBAEncodingDecoding(t *testing.T) {
test.That(t, imgB, test.ShouldResemble, decodedImgB)
test.That(t, imgA, test.ShouldResemble, decodedImgA)
}

func TestRawDepthEncodingDecoding(t *testing.T) {
img := NewEmptyDepthMap(4, 8)
for x := 0; x < 4; x++ {
for y := 0; y < 8; y++ {
img.Set(x, y, Depth(x*y))
}
}
encodedImgBytes, err := EncodeImage(context.Background(), img, utils.MimeTypeRawDepth)
test.That(t, err, test.ShouldBeNil)
reader := bytes.NewReader(encodedImgBytes)

// decode Header
conf, header, err := image.DecodeConfig(reader)
test.That(t, err, test.ShouldBeNil)
test.That(t, header, test.ShouldEqual, "vnd.viam.dep")
test.That(t, conf.Width, test.ShouldEqual, img.Bounds().Dx())
test.That(t, conf.Height, test.ShouldEqual, img.Bounds().Dy())

// decode with image package
reader = bytes.NewReader(encodedImgBytes)
imgDecoded, header, err := image.Decode(reader)
test.That(t, err, test.ShouldBeNil)
test.That(t, header, test.ShouldEqual, "vnd.viam.dep")
test.That(t, imgDecoded.Bounds(), test.ShouldResemble, img.Bounds())
test.That(t, imgDecoded.At(2, 3), test.ShouldResemble, img.At(2, 3))
test.That(t, imgDecoded.At(1, 0), test.ShouldResemble, img.At(1, 0))

// decode with rimage package
decodedImg, err := DecodeImage(context.Background(), encodedImgBytes, utils.MimeTypeRawDepth)
test.That(t, err, test.ShouldBeNil)
test.That(t, decodedImg.Bounds(), test.ShouldResemble, img.Bounds())
decodedDm, ok := decodedImg.(*DepthMap)
test.That(t, ok, test.ShouldBeTrue)
test.That(t, decodedDm.GetDepth(2, 3), test.ShouldEqual, img.GetDepth(2, 3))
test.That(t, decodedDm.GetDepth(1, 0), test.ShouldEqual, img.GetDepth(1, 0))
}

0 comments on commit 6605c78

Please sign in to comment.