mirror of
				https://github.com/pion/mediadevices.git
				synced 2025-10-31 11:56:28 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			37 lines
		
	
	
		
			1.3 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			37 lines
		
	
	
		
			1.3 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package frame
 | |
| 
 | |
| import (
 | |
| 	"encoding/binary"
 | |
| 	"fmt"
 | |
| 	"image"
 | |
| 	"image/color"
 | |
| )
 | |
| 
 | |
| func decodeZ16(frame []byte, width, height int) (image.Image, func(), error) {
 | |
| 	expectedSize := 2 * (width * height)
 | |
| 	if expectedSize  != len(frame) {
 | |
| 		return nil, func() {}, fmt.Errorf("frame length (%d) not expected size (%d)", len(frame), expectedSize)
 | |
| 	}
 | |
| 	img := image.NewGray16(image.Rect(0, 0, width, height))
 | |
| 	/*
 | |
| 		v4l specifies images in terms of series of lines which is perplexing because the
 | |
| 		example in https://www.kernel.org/doc/html/v5.9/userspace-api/media/v4l/pixfmt-z16.html
 | |
| 		seems to swap the subscript of each depth value.
 | |
| 
 | |
| 		Clear example:
 | |
| 		Width: 3, Height: 4
 | |
| 		[Z_low(x_0,y_0), Z_high(x_0,y_0), Z_low(x_1,y_0), Z_high(x_1,y_0), Z_low(x_2,y_0), Z_high(x_2,y_0),
 | |
| 		 Z_low(x_0,y_1), Z_high(x_0,y_1), Z_low(x_1,y_1), Z_high(x_1,y_1), Z_low(x_2,y_1), Z_high(x_2,y_1),
 | |
| 		 Z_low(x_0,y_2), Z_high(x_0,y_2), Z_low(x_1,y_2), Z_high(x_1,y_2), Z_low(x_2,y_2), Z_high(x_2,y_2),
 | |
| 		 Z_low(x_0,y_3), Z_high(x_0,y_3), Z_low(x_1,y_3), Z_high(x_1,y_3), Z_low(x_2,y_3), Z_high(x_2,y_3)]
 | |
| 	*/
 | |
| 	for x := 0; x < width; x++ {
 | |
| 		for y := 0; y < height; y++ {
 | |
| 			idx := 2 * (x + (y * width))
 | |
| 			z := binary.LittleEndian.Uint16(frame[idx : idx+2])
 | |
| 			img.SetGray16(x, y, color.Gray16{Y: z})
 | |
| 		}
 | |
| 	}
 | |
| 	return img, func() {}, nil
 | |
| }
 | 
