Skip to content

Commit 185caad

Browse files
committed
Support encoding "image.NRGBA64" and use bit depth depending on compression.
1 parent 8807fad commit 185caad

File tree

1 file changed

+113
-32
lines changed

1 file changed

+113
-32
lines changed

encode_highlevel.go

Lines changed: 113 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ func imageFromNRGBA(i *image.NRGBA) (*Image, error) {
7171
return out, nil
7272
}
7373

74-
func imageFromRGBA64(i *image.RGBA64) (*Image, error) {
74+
func imageFromRGBA64(i *image.RGBA64, compression CompressionFormat) (*Image, error) {
7575
min := i.Bounds().Min
7676
max := i.Bounds().Max
7777
w := max.X - min.X
@@ -82,42 +82,117 @@ func imageFromRGBA64(i *image.RGBA64) (*Image, error) {
8282
return nil, fmt.Errorf("failed to create image: %v", err)
8383
}
8484

85-
p, err := out.NewPlane(ChannelInterleaved, w, h, 10)
85+
var depth int
86+
switch compression {
87+
case CompressionAV1:
88+
depth = 12
89+
case CompressionHEVC:
90+
depth = 10
91+
default:
92+
depth = 16
93+
}
94+
p, err := out.NewPlane(ChannelInterleaved, w, h, depth)
95+
if err != nil {
96+
return nil, fmt.Errorf("failed to add plane: %v", err)
97+
}
98+
99+
if depth == 16 {
100+
p.setData(i.Pix, w*8)
101+
} else {
102+
shift := 16 - depth
103+
pix := make([]byte, w*h*8)
104+
read_pos := 0
105+
write_pos := 0
106+
for y := 0; y < h; y++ {
107+
for x := 0; x < w; x++ {
108+
r := (uint16(i.Pix[read_pos]) << 8) | uint16(i.Pix[read_pos+1])
109+
r = r >> shift
110+
pix[write_pos] = byte(r >> 8)
111+
pix[write_pos+1] = byte(r & 0xff)
112+
read_pos += 2
113+
g := (uint16(i.Pix[read_pos]) << 8) | uint16(i.Pix[read_pos+1])
114+
g = g >> shift
115+
pix[write_pos+2] = byte(g >> 8)
116+
pix[write_pos+3] = byte(g & 0xff)
117+
read_pos += 2
118+
b := (uint16(i.Pix[read_pos]) << 8) | uint16(i.Pix[read_pos+1])
119+
b = b >> shift
120+
pix[write_pos+4] = byte(b >> 8)
121+
pix[write_pos+5] = byte(b & 0xff)
122+
read_pos += 2
123+
a := (uint16(i.Pix[read_pos]) << 8) | uint16(i.Pix[read_pos+1])
124+
a = a >> shift
125+
pix[write_pos+6] = byte(a >> 8)
126+
pix[write_pos+7] = byte(a & 0xff)
127+
read_pos += 2
128+
write_pos += 8
129+
}
130+
}
131+
p.setData(pix, w*8)
132+
}
133+
134+
return out, nil
135+
}
136+
137+
func imageFromNRGBA64(i *image.NRGBA64, compression CompressionFormat) (*Image, error) {
138+
min := i.Bounds().Min
139+
max := i.Bounds().Max
140+
w := max.X - min.X
141+
h := max.Y - min.Y
142+
143+
out, err := NewImage(w, h, ColorspaceRGB, ChromaInterleavedRRGGBBAA_BE)
144+
if err != nil {
145+
return nil, fmt.Errorf("failed to create image: %v", err)
146+
}
147+
148+
var depth int
149+
switch compression {
150+
case CompressionAV1:
151+
depth = 12
152+
case CompressionHEVC:
153+
depth = 10
154+
default:
155+
depth = 16
156+
}
157+
p, err := out.NewPlane(ChannelInterleaved, w, h, depth)
86158
if err != nil {
87159
return nil, fmt.Errorf("failed to add plane: %v", err)
88160
}
89161

90-
pix := make([]byte, w*h*8)
91-
read_pos := 0
92-
write_pos := 0
93-
for y := 0; y < h; y++ {
94-
for x := 0; x < w; x++ {
95-
r := (uint16(i.Pix[read_pos]) << 8) | uint16(i.Pix[read_pos+1])
96-
r = r >> 6
97-
pix[write_pos] = byte(r >> 8)
98-
pix[write_pos+1] = byte(r & 0xff)
99-
read_pos += 2
100-
g := (uint16(i.Pix[read_pos]) << 8) | uint16(i.Pix[read_pos+1])
101-
g = g >> 6
102-
pix[write_pos+2] = byte(g >> 8)
103-
pix[write_pos+3] = byte(g & 0xff)
104-
read_pos += 2
105-
b := (uint16(i.Pix[read_pos]) << 8) | uint16(i.Pix[read_pos+1])
106-
b = b >> 6
107-
pix[write_pos+4] = byte(b >> 8)
108-
pix[write_pos+5] = byte(b & 0xff)
109-
read_pos += 2
110-
a := (uint16(i.Pix[read_pos]) << 8) | uint16(i.Pix[read_pos+1])
111-
a = a >> 6
112-
pix[write_pos+6] = byte(a >> 8)
113-
pix[write_pos+7] = byte(a & 0xff)
114-
pix[write_pos+6] = byte(a >> 8)
115-
pix[write_pos+7] = byte(a & 0xff)
116-
read_pos += 2
117-
write_pos += 8
162+
if depth == 16 {
163+
p.setData(i.Pix, w*8)
164+
} else {
165+
shift := 16 - depth
166+
pix := make([]byte, w*h*8)
167+
read_pos := 0
168+
write_pos := 0
169+
for y := 0; y < h; y++ {
170+
for x := 0; x < w; x++ {
171+
r := (uint16(i.Pix[read_pos]) << 8) | uint16(i.Pix[read_pos+1])
172+
r = r >> shift
173+
pix[write_pos] = byte(r >> 8)
174+
pix[write_pos+1] = byte(r & 0xff)
175+
read_pos += 2
176+
g := (uint16(i.Pix[read_pos]) << 8) | uint16(i.Pix[read_pos+1])
177+
g = g >> shift
178+
pix[write_pos+2] = byte(g >> 8)
179+
pix[write_pos+3] = byte(g & 0xff)
180+
read_pos += 2
181+
b := (uint16(i.Pix[read_pos]) << 8) | uint16(i.Pix[read_pos+1])
182+
b = b >> shift
183+
pix[write_pos+4] = byte(b >> 8)
184+
pix[write_pos+5] = byte(b & 0xff)
185+
read_pos += 2
186+
a := (uint16(i.Pix[read_pos]) << 8) | uint16(i.Pix[read_pos+1])
187+
a = a >> shift
188+
pix[write_pos+6] = byte(a >> 8)
189+
pix[write_pos+7] = byte(a & 0xff)
190+
read_pos += 2
191+
write_pos += 8
192+
}
118193
}
194+
p.setData(pix, w*8)
119195
}
120-
p.setData(pix, w*8)
121196

122197
return out, nil
123198
}
@@ -290,7 +365,13 @@ func EncodeFromImage(img image.Image, compression CompressionFormat, params ...E
290365
}
291366
out = tmp
292367
case *image.RGBA64:
293-
tmp, err := imageFromRGBA64(i)
368+
tmp, err := imageFromRGBA64(i, compression)
369+
if err != nil {
370+
return nil, fmt.Errorf("failed to create image: %v", err)
371+
}
372+
out = tmp
373+
case *image.NRGBA64:
374+
tmp, err := imageFromNRGBA64(i, compression)
294375
if err != nil {
295376
return nil, fmt.Errorf("failed to create image: %v", err)
296377
}

0 commit comments

Comments
 (0)