Skip to content

Task #614: export-png --dpi 옵션 — PNG pHYs chunk 메타데이터#734

Closed
oksure wants to merge 2 commits into
edwardkim:develfrom
oksure:contrib/export-png-dpi
Closed

Task #614: export-png --dpi 옵션 — PNG pHYs chunk 메타데이터#734
oksure wants to merge 2 commits into
edwardkim:develfrom
oksure:contrib/export-png-dpi

Conversation

@oksure

@oksure oksure commented May 9, 2026

Copy link
Copy Markdown
Contributor

요약

export-png 명령에 --dpi <값> 옵션을 추가합니다.

  • PNG pHYs chunk 에 DPI 메타데이터를 삽입하여 인쇄 워크플로우에서 크기 힌트를 제공합니다
  • --scale 미지정 시 scale = dpi / 96.0 자동 계산 (예: --dpi 300 → scale 3.125)
  • 실제 래스터 픽셀 수에는 영향 없음 (메타데이터 전용)

변경 사항

  • PngExportOptionsdpi: Option<f64> 필드 추가
  • CLI --dpi <값> 옵션 파싱 + 도움말 갱신
  • Skia PNG 인코딩 후 pHYs chunk 후처리 삽입 (IHDR 직후, PNG spec §11.3.5.3)
  • CRC32 자체 구현 (외부 의존성 없음)
  • 단위 테스트: pHYs 삽입 위치/PPM 값 검증, CRC32 known-value 검증

사용 예시

rhwp export-png input.hwp --dpi 300           # scale 3.125 자동, 300 DPI 메타데이터
rhwp export-png input.hwp --scale 2 --dpi 150 # scale 2 명시, 150 DPI 메타데이터

테스트

cargo test && cargo clippy -- -D warnings  # 0 failed, 0 warnings

Closes #614

감사합니다.

…-scale

- PngExportOptions 에 dpi: Option<f64> 필드 추가
- --dpi <값> CLI 옵션 추가 (도움말 포함)
- --scale 미지정 + --dpi 만 지정 시 scale = dpi / 96.0 자동 계산
- Skia PNG 인코딩 후 pHYs chunk 후처리 삽입 (IHDR 직후)
- pHYs chunk: X/Y pixels-per-meter + unit=meter (PNG spec §11.3.5.3)
- 단위 테스트: pHYs 삽입 위치 + PPM 값 + CRC32 검증

Closes edwardkim#614

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings May 9, 2026 10:32

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

export-png 명령에 --dpi <값> 옵션을 추가해, PNG 출력에 DPI 메타데이터를 pHYs chunk로 기록하여 인쇄 워크플로우에서 크기 힌트를 제공하는 변경입니다. 또한 --scale 미지정 시 scale = dpi / 96.0 자동 계산 로직이 렌더링 경로에 포함됩니다.

Changes:

  • export-png CLI에 --dpi 옵션 추가 및 도움말/옵션 파싱 업데이트
  • PngExportOptionsdpi: Option<f64> 추가, --dpi만 지정 시 scale 자동 산출
  • Skia PNG 인코딩 결과 바이트에 pHYs chunk를 삽입하는 후처리 및 CRC32 구현/테스트 추가

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
src/main.rs --dpi 옵션 도움말/파싱 추가 및 PngExportOptions로 전달
src/document_core/queries/rendering.rs DPI→scale 자동 계산, PNG pHYs chunk 삽입 로직 및 CRC32/단위 테스트 추가

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/document_core/queries/rendering.rs Outdated
Comment on lines +259 to +271
let ppm = (dpi / 0.0254).round() as u32;
// PNG 구조: 8-byte signature + chunks (IHDR first, then others)
// 각 chunk: 4-byte length + 4-byte type + data + 4-byte CRC
if png.len() < 8 {
return png;
}
let mut pos = 8; // signature 이후
// IHDR chunk 끝 위치 찾기
if pos + 8 > png.len() {
return png;
}
let ihdr_len = u32::from_be_bytes([png[pos], png[pos + 1], png[pos + 2], png[pos + 3]]) as usize;
let ihdr_end = pos + 4 + 4 + ihdr_len + 4; // length + type + data + CRC
Comment thread src/document_core/queries/rendering.rs Outdated
if png.len() < 8 {
return png;
}
let mut pos = 8; // signature 이후
Comment on lines +243 to +250
let png_bytes = SkiaLayerRenderer::new()
.with_font_paths(&options.font_paths)
.render_png_with_options(&layer_tree, raster_options)
.render_png_with_options(&layer_tree, raster_options)?;

if let Some(dpi) = options.dpi {
Ok(inject_png_phys(png_bytes, dpi))
} else {
Ok(png_bytes)
- PNG 시그니처 8바이트 검증 추가
- IHDR chunk 타입 (b"IHDR") 및 data length (=13) 검증
- ihdr_end 계산에 checked_add 사용 (오버플로우 방지)
- 불필요한 mut 제거 (pos 변수)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@oksure

oksure commented May 9, 2026

Copy link
Copy Markdown
Contributor Author

Copilot 리뷰 피드백을 9758fab 에서 반영했습니다:

  1. PNG 시그니처 + IHDR 타입/length 검증 — 손상된 바이트 입력 시 원본 반환
  2. checked_addihdr_end 오버플로우 방지
  3. let mut poslet pos — 불필요한 가변성 제거

통합 테스트(export_options + dpi 경로)는 native-skia feature 필요로 CI에서만 실행 가능합니다. 단위 테스트로 pHYs 삽입 로직의 정확성을 커버하고 있습니다.

edwardkim added a commit that referenced this pull request May 9, 2026
PR #734 (@oksure) 옵션 A 처리 — 2 commits cherry-pick + no-ff merge.

본질 정정 (2 files, +164/-5):
- src/main.rs (+21/-1): CLI --dpi 옵션 파싱 + 도움말 갱신 + PngExportOptions 영역 dpi: Option<f64> 필드 추가
- src/document_core/queries/rendering.rs (+143/-4):
  · scale 결정 우선순위 갱신 — --dpi 만 지정 시 scale = dpi/96.0 자동
  · inject_png_phys 후처리 함수 — PNG IHDR 직후 + 첫 IDAT 직전 영역 영역 pHYs chunk 삽입 (PNG spec §11.3.5.3)
  · CRC32 자체 구현 (외부 의존성 없음)
  · 신규 unit tests 2건: inject_png_phys_inserts_after_ihdr / png_crc32_known_value

Copilot 리뷰 반영 (commit 9758fab): 방어 검증 강화
- PNG 시그니처 8바이트 검증
- IHDR chunk 타입 (b"IHDR") + data length (=13) 검증
- ihdr_end 계산 영역 checked_add (오버플로우 방지)
- 불필요한 mut 제거

opt-in 영역 영역:
- --dpi 미지정 시 기존 동작 100% 보존
- pHYs chunk 영역 영역 표준 PNG 메타데이터 (픽셀 데이터 무영향)

자기 검증:
- cherry-pick 충돌 0건
- cargo build/test --release ✅ ALL GREEN
- 신규 unit tests ✅ 2 PASS
- 광범위 sweep 7 fixture / 170 페이지 / **회귀 0** ✅
- 시각 판정 면제 합리 (PNG 메타데이터 영역 영역 픽셀 데이터 무영향, feedback_visual_judgment_authority 정합)

closes #614
edwardkim added a commit that referenced this pull request May 9, 2026
- mydocs/pr/archives/pr_734_review.md: 검토 문서 archives 이동
- mydocs/pr/archives/pr_734_report.md: 처리 보고서 작성
  · export-png --dpi 옵션 (Issue #614 closes)
  · PNG pHYs chunk 영역 인쇄 워크플로우 메타데이터
  · 작업지시자 실 sample 검증 통과 (samples/통합재정통계(2010.11월).hwp 영역 4 패턴)
  · 시각 판정 면제 합리 (PNG 메타데이터 영역 영역 픽셀 데이터 무영향)
- mydocs/orders/20260510.md: PR #734 항목 추가 (5/10 사이클 영역 영역 8건 처리)
- mydocs/manual/export_png_command.md: --dpi 옵션 매뉴얼 현행화
  · 옵션 표 영역 --dpi 추가
  · 옵션 우선순위 갱신 (--dpi auto-scale)
  · DPI 메타데이터 영역 영역 별도 절 추가 (PNG spec §11.3.5.3 정합)
  · 사용 예시 + 출력 dimension 표 갱신 (--dpi 300 영역 영역)
  · 출력 형식 영역 메타데이터 명시
  · 비목표 영역 갱신 (PR #720/#734 영역 영역 진전 반영)
@edwardkim

Copy link
Copy Markdown
Owner

@oksure 님, 검토 + 머지 완료했습니다.

처리 결과

옵션 A (2 commits cherry-pick + no-ff merge `d76e86fc`) 로 처리.

자기 검증

  • `cargo build/test --release` ✅ ALL GREEN
  • 신규 unit tests ✅ 2 PASS (`inject_png_phys_inserts_after_ihdr` + `png_crc32_known_value`)
  • 광범위 sweep (7 fixture / 170 페이지) ✅ 170 same / 0 diff

작업지시자 실 sample 검증 ✅

`samples/통합재정통계(2010.11월).hwp` 영역 영역 4 패턴 검증 — 모두 정합 영역:

패턴 pHYs chunk PPM 변환 DPI IHDR 폭 scale
baseline ❌ 부재 794 1.0
`--dpi 96` 3780 96 DPI 794 1.0
`--dpi 300` 11811 300 DPI 2481 3.125 (auto)
`--scale 2 --dpi 150` 5906 150 DPI 1588 2.0 (명시)

검증 영역 영역:

  • `--dpi` 미지정 시 pHYs 부재 (opt-in 정합)
  • 모든 DPI 영역 영역 정확 변환 (`ppm = round(dpi / 0.0254)`)
  • auto-scale 영역 영역 정합 (`scale = dpi / 96.0`)
  • 명시 `--scale` 영역 영역 우선 + `--dpi` 영역 영역 메타데이터 만 영향
  • pHYs chunk 영역 영역 IHDR 직후 삽입 (PNG spec §11.3.5.3 정합)
  • pHYs chunk 영역 영역 21 bytes 추가 (4+4+9+4 정합)

시각 판정 면제

`feedback_visual_judgment_authority` 정합 — PNG 메타데이터 영역 영역 (픽셀 데이터 무영향), SVG 시각 출력 무변경, 결정적 검증 통과 영역 영역 시각 판정 면제 합리.

매뉴얼 현행화

`mydocs/manual/export_png_command.md` 영역 `--dpi` 옵션 추가 영역 영역 매뉴얼 현행화 완료 (옵션 표 + 옵션 우선순위 + DPI 메타데이터 별도 절 + 사용 예시 + 출력 dimension 표 + 비목표 갱신).

처리 보고서: `mydocs/pr/archives/pr_734_report.md`.

@oksure20+ 사이클 컨트리뷰션 영역 — 5/10 사이클 영역 영역 PR #720/#723/#725/#728/#729/#730/#732/#734 영역 8건 처리 완료 영역.

@edwardkim edwardkim closed this May 9, 2026
edwardkim added a commit that referenced this pull request May 9, 2026
…wen-VL / LLaVA)

PR #735 (@oksure) 옵션 A 처리 — 2 commits cherry-pick + 수동 충돌 해결 + no-ff merge.

본질 정정 (2 files, +71/-8):
- src/document_core/queries/rendering.rs (+61/-3): VlmTarget enum 1 → 6 variants 확장 (Claude / Gpt4vLow / Gpt4vHigh / Gemini / QwenVl / Llava) + constraints() 메서드 각 provider 한도 (edge / pixels) + from_str() 하이픈/밑줄 정규화 + 축약 별칭 (gpt4v / qwen) + all_names() 헬퍼 + 신규 unit tests 2건 (vlm_target_from_str_all_variants 12 케이스 / vlm_target_constraints_are_sane 6 variants sanity check)
- src/main.rs (+10/-5): CLI 도움말 영역 6종 프리셋 한 줄 설명 + 에러 메시지 영역 VlmTarget::all_names() 동기화

추가 프리셋:
- gpt4v-low: 512 px / 262K (GPT-4V low detail)
- gpt4v-high: 2000 px / 1.54 MP (GPT-4V high, 별칭 gpt4v)
- gemini: 3072 px / 9.44 MP (Google Gemini)
- qwen-vl: 2240 px / 5.02 MP (Qwen-VL 28×28 patch, 별칭 qwen)
- llava: 672 px / 452K (LLaVA / OSS CLIP backbone)

Copilot 리뷰 반영 (commit 2883733): from_str 정규화 후 dead arm 제거 + 별칭 도움말 동기화 (하이픈/밑줄 모두 허용 명시).

본 환경 cherry-pick 영역 영역 PR #734 (Task #614 --dpi) 영역 영역 동일 파일 영역 영역 누적 변경 영역 영역 충돌 발생 영역 영역 → **수동 통합** (PR #734 의 --dpi 보존 + PR #735 의 VLM 6종 보존).

자기 검증:
- cherry-pick 2 commits 영역 영역 수동 충돌 해결 (main.rs 도움말 + rendering.rs 테스트 모듈)
- cargo build/test --release ✅ ALL GREEN (native-skia feature 영역 영역 도)
- VLM unit tests ✅ 2 PASS
- 광범위 sweep 7 fixture / 170 페이지 / **회귀 0** ✅
- --dpi + --vlm-target 통합 동작 검증 ✅ (samples/통합재정통계(2010.11월).hwp 영역 영역 --vlm-target gemini 단독 + --vlm-target gpt4v --dpi 200 동시 — pHYs ppm 7874 = 200 DPI 정합)

opt-in 영역 영역:
- --vlm-target 미지정 시 기존 동작 100% 보존
- 시각 판정 면제 합리 (CLI 옵션 + enum 확장 영역 영역 픽셀 데이터 무영향, feedback_visual_judgment_authority 정합)

closes #613
edwardkim added a commit that referenced this pull request May 9, 2026
…M 프리셋 표 갱신

- mydocs/pr/archives/pr_735_review.md: 검토 문서 archives 이동
- mydocs/pr/archives/pr_735_report.md: 처리 보고서 작성
  · VLM 프리셋 1 → 6 variants 확장 (Issue #613 closes)
  · PR #734 + PR #735 동일 파일 누적 변경 영역 영역 수동 통합
  · PR #734 + PR #735 통합 검증 ✅ (--vlm-target + --dpi 독립 동작 입증)
  · 시각 판정 면제 합리 (CLI + enum 확장 영역 영역 픽셀 데이터 무영향)
- mydocs/orders/20260510.md: PR #735 항목 추가 (5/10 사이클 영역 영역 9건 처리)
- mydocs/manual/export_png_command.md: VLM 프리셋 표 갱신 (1 → 6 variants) + 비목표 영역 갱신 (#613 완료)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants