MCPcopy Create free account
hub / github.com/JasonLSC/GSCodec_Studio / encode

Method encode

gsplat/compression/post_training/codec.py:106–223  ·  view source on GitHub ↗
(self, frame_dir: Path, splats: TensorDict, quant_ctx: QuantizationContext)

Source from the content-addressed store, hash-verified

104 self.config = config
105
106 def encode(self, frame_dir: Path, splats: TensorDict, quant_ctx: QuantizationContext) -> CodecArtifacts:
107 frame_dir.mkdir(parents=True, exist_ok=True)
108 files: Dict[str, Dict[str, Any]] = {}
109
110 for name, tensor in splats.items():
111 stats = quant_ctx.field_stats.get(name)
112 if stats is None:
113 raise KeyError(f"Quantization stats missing for field '{name}'")
114
115 method = getattr(stats, "method", "scalar")
116 codebook_size = stats.codebook_shape[0] if getattr(stats, "codebook_shape", None) else 0
117 logger.info(
118 "PNG codec encoding field '%s'; method=%s bitwidth=%d channels=%d codebook_size=%d",
119 name,
120 method,
121 stats.bitwidth,
122 stats.channels,
123 codebook_size,
124 )
125 int_tensor = quant_ctx.int_values.get(name)
126 if int_tensor is None:
127 raise ValueError(
128 f"Field '{name}' requires integer cache; set store_as_int=True in QuantFieldConfig."
129 )
130
131 n_points = int_tensor.shape[0]
132 sidelen = int(math.isqrt(n_points))
133 if sidelen * sidelen != n_points:
134 raise ValueError(f"PNG codec requires perfect-square length after mapping, got {n_points} for '{name}'.")
135
136 flattened = int_tensor.reshape(n_points, -1)
137 channels = flattened.shape[1]
138
139 if stats.bitwidth > 16:
140 raise ValueError(f"PNG codec only supports up to 16-bit data, got {stats.bitwidth} for '{name}'.")
141
142 # Skip fields with 0 channels (empty fields)
143 if channels == 0:
144 logger.info(f"Skipping field '{name}' with 0 channels")
145 continue
146
147 levels = (1 << stats.bitwidth) - 1
148 clamped = torch.clamp(flattened, 0, levels)
149 array = clamped.detach().cpu().numpy()
150
151 data_shape = list(stats.tensor_shape or tensor.shape)
152
153 if name == "means" and method == "scalar":
154 array16 = array.astype(np.uint16)
155 image16 = array16.reshape(sidelen, sidelen, channels)
156 low = (image16 & 0xFF).astype(np.uint8)
157 high = (image16 >> 8).astype(np.uint8)
158 low_path = frame_dir / f"{name}_l.png"
159 high_path = frame_dir / f"{name}_h.png"
160 imageio.imwrite(low_path, low)
161 imageio.imwrite(high_path, high)
162 files[name] = {
163 "type": "png_split16",

Callers

nothing calls this directly

Calls 2

CodecArtifactsClass · 0.85
getMethod · 0.80

Tested by

no test coverage detected