/** * 서명 그림 테스트용 그림 파일 머리 — 테스트 전용 도우미 (앱 코드에서 import 하지 않는다). * * 형식 확인(signature-image-format.ts)은 파일 앞부분만 본다 — 여기서는 그 앞부분과, 크기를 맞출 채움 바이트만 만든다 * (실제로 그릴 수 있는 그림일 필요는 없다). * * 위치: src 밖(test/) — cpu-time.ts 와 같은 이유로 빌드·커버리지에 들어가지 않는다. * 단위 테스트는 `@/../test/image-fixtures`, e2e 는 `./image-fixtures` 로 부른다. */ /** PNG 서명 + IHDR(가로·세로·비트 깊이·색 형식) — CRC 는 보지 않으므로 비워 둔다. `size` 바이트가 되게 0 으로 채운다 */ export function pngBytes(width: number, height: number, size = 33): Buffer { const data = Buffer.alloc(Math.max(size, 33)); Buffer.from([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]).copy(data); data.writeUInt32BE(13, 8); data.write('IHDR', 12, 'ascii'); data.writeUInt32BE(width, 16); data.writeUInt32BE(height, 20); data[24] = 8; // 비트 깊이 data[25] = 6; // 색 형식 RGBA return data; } /** GIF 머리 (논리 화면의 가로·세로, 리틀 엔디언) */ export function gifBytes( width: number, height: number, version = 'GIF89a', ): Buffer { const data = Buffer.alloc(13); data.write(version, 0, 'ascii'); data.writeUInt16LE(width, 6); data.writeUInt16LE(height, 8); return data; } /** SOI + APP0(JFIF) + (선택) 표지 앞 채움 바이트 + SOFn(세로·가로) + EOI */ export function jpegBytes( width: number, height: number, options: { sof?: number; fill?: boolean } = {}, ): Buffer { const app0 = Buffer.from([ 0xff, 0xe0, 0x00, 0x10, 0x4a, 0x46, 0x49, 0x46, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, ]); const sof = Buffer.from([ 0xff, options.sof ?? 0xc0, 0x00, 0x11, 0x08, (height >> 8) & 0xff, height & 0xff, (width >> 8) & 0xff, width & 0xff, 0x03, 0x01, 0x22, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, ]); return Buffer.concat([ Buffer.from([0xff, 0xd8]), app0, ...(options.fill ? [Buffer.from([0xff, 0xff])] : []), sof, Buffer.from([0xff, 0xd9]), ]); } /** WebP 머리 — 'RIFF' 크기 'WEBP' 첫 덩어리(VP8 · VP8L · VP8X). `size` 바이트가 되게 0 으로 채운다 (바깥 이미지 중계 — 9단계) */ export function webpBytes(chunk = 'VP8 ', size = 30): Buffer { const data = Buffer.alloc(Math.max(size, 20)); data.write('RIFF', 0, 'ascii'); data.writeUInt32LE(data.length - 8, 4); data.write('WEBP', 8, 'ascii'); data.write(chunk, 12, 'ascii'); return data; }