MCPcopy Index your code
hub / github.com/simstudioai/sim / parseStretchDibits

Function parseStretchDibits

apps/sim/lib/pptx-renderer/utils/emf-parser.ts:195–268  ·  view source on GitHub ↗

* Parse a STRETCHDIBITS record and extract the bitmap as ImageData.

(
  data: Uint8Array,
  view: DataView,
  offset: number,
  _recordSize: number
)

Source from the content-addressed store, hash-verified

193 * Parse a STRETCHDIBITS record and extract the bitmap as ImageData.
194 */
195function parseStretchDibits(
196 data: Uint8Array,
197 view: DataView,
198 offset: number,
199 _recordSize: number
200): EmfContent | null {
201 // STRETCHDIBITS record layout (offsets from record start):
202 // 0: type(4), 4: size(4)
203 // 8: rclBounds (16 bytes)
204 // 24: xDest(4), 28: yDest(4)
205 // 32: xSrc(4), 36: ySrc(4)
206 // 40: cxSrc(4), 44: cySrc(4)
207 // 48: offBmiSrc(4), 52: cbBmiSrc(4)
208 // 56: offBitsSrc(4), 60: cbBitsSrc(4)
209 // 64: iUsageSrc(4), 68: dwRop(4)
210 // 72: cxDest(4), 76: cyDest(4)
211 if (offset + 80 > data.length) return null
212
213 const offBmiSrc = view.getUint32(offset + 48, true)
214 const cbBmiSrc = view.getUint32(offset + 52, true)
215 const offBitsSrc = view.getUint32(offset + 56, true)
216 const cbBitsSrc = view.getUint32(offset + 60, true)
217
218 if (cbBmiSrc === 0 || cbBitsSrc === 0) return null
219
220 const bmiStart = offset + offBmiSrc
221 if (bmiStart + 40 > data.length) return null
222
223 // Parse BITMAPINFOHEADER
224 const biWidth = view.getInt32(bmiStart + 4, true)
225 const biHeight = view.getInt32(bmiStart + 8, true)
226 const biBitCount = view.getUint16(bmiStart + 14, true)
227 const biCompression = view.getUint32(bmiStart + 16, true)
228
229 // Only support uncompressed RGB bitmaps
230 if (biCompression !== BI_RGB) return null
231 if (biBitCount !== 24 && biBitCount !== 32) return null
232
233 const width = Math.abs(biWidth)
234 const height = Math.abs(biHeight)
235 if (width === 0 || height === 0 || width > 8192 || height > 8192) return null
236
237 const bitsStart = offset + offBitsSrc
238 if (bitsStart + cbBitsSrc > data.length) return null
239
240 const bitsData = data.subarray(bitsStart, bitsStart + cbBitsSrc)
241
242 // Negative height means top-down row order; positive means bottom-up
243 const topDown = biHeight < 0
244
245 const imageData = new ImageData(width, height)
246 const bytesPerPixel = biBitCount / 8
247 // DIB rows are padded to 4-byte boundaries
248 const rowStride = Math.ceil((width * bytesPerPixel) / 4) * 4
249
250 for (let y = 0; y < height; y++) {
251 const srcRow = topDown ? y : height - 1 - y
252 const srcOffset = srcRow * rowStride

Callers 1

parseEmfContentFunction · 0.85

Calls

no outgoing calls

Tested by

no test coverage detected