# justjp2 — Pure Rust JPEG 2000 Implementation Roadmap

> 각 Phase/Step은 해당 테스트를 통과해야 완료로 간주한다.
> 테스트 경로: `tests/` 디렉토리 또는 각 모듈 내 `#[cfg(test)]`

---

## Phase 0: 기반 타입 및 유틸리티

모든 모듈이 공유하는 기본 타입, 에러, 바이트 I/O를 정의한다.

### Step 0.1 — 기본 타입 정의 (`types.rs`)

JPEG 2000에서 사용하는 상수와 enum을 정의한다. Rust 네이티브 타입(i32, u32 등)을 직접 사용.

```
- J2K_MAXRLVLS (33), J2K_MAXBANDS (97), J2K_MAX_CBLK_SIZE (64), MQC_NUMCTXS (19)
- ProgOrder enum (LRCP, RLCP, RPCL, PCRL, CPRL)
- ColorSpace enum (Unknown, Unspecified, sRGB, Grayscale, YCC, CMYK, eYCC)
- CodecFormat enum (J2K, JP2)
- QuantStyle enum (None, ScalarImplicit, ScalarExplicit)
```

**테스트**: `tests/phase0_types.rs`
```rust
#[test] fn maxbands_value()           // 3*33-2 == 97
#[test] fn maxrlvls_value()           // 33
#[test] fn prog_order_roundtrip()     // enum → u8 → enum
#[test] fn prog_order_invalid()       // 범위 밖 값 → None
#[test] fn color_space_default()      // Unknown이 기본값
#[test] fn codec_format_variants()    // J2K, JP2 구분
#[test] fn quant_style_variants()     // 양자화 스타일 값
```

### Step 0.2 — 에러 타입 (`error.rs`)

라이브러리 전역 에러 타입을 정의한다.

```
- Jp2Error enum (Io, InvalidMarker, InvalidData, UnsupportedFeature, BufferTooSmall, ...)
- Result<T> = std::result::Result<T, Jp2Error>
- Display, std::error::Error impl
```

**테스트**: `tests/phase0_error.rs`
```rust
#[test] fn error_display()            // 에러 메시지 포맷
#[test] fn error_from_io()            // std::io::Error → Jp2Error 변환
#[test] fn error_is_send_sync()       // Send + Sync 보장
#[test] fn error_source()             // std::error::Error::source() 체인
```

### Step 0.3 — 바이트 I/O (`stream.rs`)

Big-endian 바이트 읽기/쓰기 함수 및 커서 기반 Reader/Writer를 정의한다.

```
- read_u8, read_u16_be, read_u32_be, read_u64_be (슬라이스 함수)
- write_u8, write_u16_be, write_u32_be (슬라이스 함수)
- SliceReader: read, skip, seek, tell, remaining
- VecWriter: write, as_slice, into_vec
```

**테스트**: `tests/phase0_stream.rs`
```rust
#[test] fn read_u16_be_test()         // [0xFF, 0x4F] → 0xFF4F
#[test] fn read_u32_be_test()         // 4바이트 BE 읽기
#[test] fn write_roundtrip_u16()      // write → read 왕복
#[test] fn write_roundtrip_u32()      // write → read 왕복
#[test] fn slice_reader_remaining()   // 남은 바이트 수 추적
#[test] fn slice_reader_skip()        // skip 후 위치 확인
#[test] fn slice_reader_seek()        // seek 후 위치 확인
#[test] fn slice_reader_read_bytes()  // n바이트 읽기
#[test] fn slice_reader_read_u64_be() // u64 BE 읽기
#[test] fn slice_reader_seek_to_end_is_ok() // 끝까지 seek OK
#[test] fn vec_writer_basic()         // VecWriter 기본 동작
#[test] fn vec_writer_write_bytes()   // 바이트 슬라이스 쓰기
#[test] fn vec_writer_u64()           // u64 BE 쓰기
#[test] fn read_past_end_returns_err()// 범위 초과 시 에러
```

---

## Phase 1: 비트 레벨 기초 모듈

비트 단위 I/O와 태그 트리 — 상위 모듈의 기반이 되는 최하위 모듈.

### Step 1.1 — Bit I/O (`bio.rs`)

비트 단위 읽기/쓰기. MQC, T1, T2에서 사용한다.

```
- BioWriter: init, putbit, write(value, nbits), flush, numbytes
- BioReader: init, getbit, read(nbits), inalign, numbytes
- 0xFF 바이트 뒤 bit-stuffing 처리
```

**테스트**: `tests/phase1_bio.rs`
```rust
#[test] fn write_single_bits()        // 비트 하나씩 쓰고 결과 확인
#[test] fn write_nbits()              // write(0b1101, 4) 검증
#[test] fn read_single_bits()         // 비트 하나씩 읽기
#[test] fn read_nbits()               // read(4) → 0b1101
#[test] fn write_read_roundtrip()     // write 후 read로 동일 값 복원
#[test] fn flush_pads_to_byte()       // flush 후 바이트 정렬 확인
#[test] fn inalign_skips_padding()    // inalign 후 바이트 경계 정렬
#[test] fn bit_stuffing_after_ff()    // 0xFF 뒤 stuff bit 삽입/스킵
#[test] fn numbytes_tracking()        // 처리된 바이트 수 정확성
#[test] fn empty_stream()             // 빈 스트림 처리
#[test] fn multi_byte_roundtrip()     // 다양한 비트폭 데이터 왕복
```

### Step 1.2 — 태그 트리 (`tgt.rs`)

코드블록 inclusion/zero-bitplane 정보를 계층적으로 인코딩하는 트리.

```
- TgtNode { value, low, known }
- TgtTree: create(w, h), reset, setvalue, encode, decode
- 부모 노드 자동 생성 (ceil 기반 계층)
```

**테스트**: `tests/phase1_tgt.rs`
```rust
#[test] fn create_1x1()               // 1x1 트리 → 노드 1개
#[test] fn create_4x4()               // 4x4 트리 → 올바른 계층 수
#[test] fn create_3x2()               // 비정방 트리
#[test] fn setvalue_and_read()        // 값 설정 후 확인
#[test] fn reset_clears_state()       // reset 후 초기 상태
#[test] fn encode_decode_roundtrip()  // 인코딩 → 디코딩 값 일치
#[test] fn encode_threshold()         // threshold 이하만 인코딩
#[test] fn multi_leaf_encode_decode() // 여러 리프 순차 인코딩/디코딩
#[test] fn parent_propagation()       // 부모 노드 값 전파 확인
```

---

## Phase 2: MQ 산술 코더

EBCOT (T1)의 핵심. 컨텍스트 기반 이진 산술 코딩.

### Step 2.1 — MQ 코더 상태 테이블

47개 확률 상태 (Qe, MPS 전이, LPS 전이, MPS switch) 테이블.

```
- MqcState { qe: u32, nmps: u8, nlps: u8, switch: bool }
- MQC_STATES: [MqcState; 47] — ITU-T T.800 Table D.2
```

### Step 2.2 — MQ 인코더

```
- MqcEncoder: init, encode(ctx, bit), flush
- 19개 컨텍스트 (MQC_NUMCTXS)
- resetstates, setstate, segmark
- bypass 모드: bypass_init, bypass_enc, bypass_flush
- erterm (에러 종료), restart_init (재시작)
```

### Step 2.3 — MQ 디코더

```
- MqcDecoder: new(data), new_raw(data), decode(ctx), raw_decode
- renormalize, bytein (0xFF 핸들링)
- resetstates, setstate
```

> 상태 테이블 + 인코더 + 디코더를 `mqc.rs` 하나에 통합 구현.

**테스트**: `tests/phase2_mqc.rs`
```rust
// 상태 테이블
#[test] fn state_count()              // 47개 상태
#[test] fn state0_qe()                // state[0].qe == 0x5601
#[test] fn state46_is_uniform()       // 마지막 상태 확인
#[test] fn mps_transition_valid()     // nmps 인덱스 범위 확인
#[test] fn lps_transition_valid()     // nlps 인덱스 범위 확인
// 인코더
#[test] fn encode_single_bit()        // 1비트 인코딩
#[test] fn encode_sequence()          // 여러 비트 시퀀스
#[test] fn flush_produces_valid()     // flush 후 유효한 바이트열
#[test] fn numbytes_after_encode()    // 인코딩 후 바이트 수
#[test] fn context_switching()        // 컨텍스트 간 전환
#[test] fn resetstates_enc()          // 상태 리셋 후 기본값
#[test] fn bypass_mode_encode()       // raw 바이패스 모드
#[test] fn bypass_mode_roundtrip()    // 바이패스 모드 왕복
#[test] fn erterm_flush()             // 에러 종료 모드
#[test] fn segmark_roundtrip()        // 세그먼트 마커 왕복
// 디코더
#[test] fn decode_single_bit()        // 1비트 디코딩
#[test] fn encode_decode_roundtrip()  // enc → dec 완전 일치
#[test] fn raw_mode_roundtrip()       // raw 모드 왕복
#[test] fn long_sequence_roundtrip()  // 1000비트 시퀀스 왕복
#[test] fn multi_context_roundtrip()  // 여러 컨텍스트 왕복
#[test] fn ff_byte_handling()         // 0xFF 바이트 경계 처리
#[test] fn all_zeros_roundtrip()      // 전부 0 왕복
#[test] fn all_ones_roundtrip()       // 전부 1 왕복
#[test] fn setstate_affects_coding()  // 다른 초기 상태 → 다른 결과
```

---

## Phase 3: Tier-1 코딩 (EBCOT 블록 코더)

코드블록 단위의 비트플레인 인코딩/디코딩. MQC 위에 구축.

### Step 3.1 — T1 컨텍스트 계산 (`t1_ctx.rs`)

이웃 비트플레인 상태로부터 MQC 컨텍스트 번호를 계산한다.

```
- significance context (ZC): 9가지, orient(HL/LH/HH/LL)에 따라 다름
- sign context (SC): 5가지
- magnitude refinement context (MAG): 3가지
- 플래그 비트 레이아웃 (SIGMA, CHI, MU, PI)
```

**테스트**: `tests/phase3_t1_ctx.rs`
```rust
#[test] fn zc_context_no_neighbors()  // 이웃 없으면 ctx 0
#[test] fn zc_context_hl_band()       // HL 밴드 컨텍스트 테이블
#[test] fn zc_context_lh_band()       // LH 밴드 컨텍스트 테이블
#[test] fn zc_context_hh_band()       // HH 밴드 컨텍스트 테이블
#[test] fn sc_context_positive()      // 양수 부호 컨텍스트
#[test] fn sc_context_negative()      // 음수 부호 컨텍스트
#[test] fn mag_context_first_ref()    // 첫 리파인먼트
#[test] fn mag_context_subsequent()   // 이후 리파인먼트
```

### Step 3.2 — T1 코딩 패스 (`t1.rs`)

세 가지 코딩 패스: Significance Propagation, Magnitude Refinement, Cleanup.

```
- T1 { data: Vec<i32>, flags: Vec<u32>, w, h, mqc }
- encode_cblk / decode_cblk
- sigpass, refpass, clnpass (enc/dec 각각)
- BYPASS, RESET, TERMALL, VSC, CAUSAL 모드 지원
```

**테스트**: `tests/phase3_t1.rs`
```rust
// 컨텍스트 (Step 3.1)
#[test] fn zc_context_no_neighbors()      // 이웃 없으면 ctx 0
#[test] fn zc_context_hl_band()           // HL 밴드 컨텍스트
#[test] fn zc_context_lh_band()           // LH 밴드 컨텍스트
#[test] fn zc_context_hh_band()           // HH 밴드 컨텍스트
#[test] fn sc_context_positive()          // 양수 부호 컨텍스트
#[test] fn sc_context_negative()          // 음수 부호 컨텍스트
#[test] fn mag_context_first_ref()        // 첫 리파인먼트
#[test] fn mag_context_subsequent()       // 이후 리파인먼트
// 인코드/디코드 왕복 (Step 3.2)
#[test] fn encode_decode_zero_block()     // 전부 0인 블록
#[test] fn encode_decode_constant_block() // 동일 값 블록
#[test] fn encode_decode_gradient()       // 그라디언트 패턴
#[test] fn encode_decode_random_4x4()     // 4x4 랜덤 데이터
#[test] fn encode_decode_64x64()          // 최대 코드블록 크기
#[test] fn encode_decode_signed()         // 음수 포함 데이터
#[test] fn multiple_passes_count()        // 패스 수 = 3*numbps - 2
// 코드블록 스타일 모드
#[test] fn bypass_mode()                  // BYPASS(LAZY) 모드 왕복
#[test] fn reset_mode()                   // RESET 모드 왕복
#[test] fn termall_mode()                 // TERMALL 모드 왕복
```

---

## Phase 4: 이산 웨이블릿 변환 (DWT)

공간→주파수 도메인 변환. 5/3 (가역) 및 9/7 (비가역).

### Step 4.1 — 1D 리프팅

```
- dwt53_forward_1d / dwt53_inverse_1d (가역 5/3, 정수)
- dwt97_forward_1d / dwt97_inverse_1d (비가역 9/7, 실수)
- 경계 대칭 확장 (mirror), split/merge 내부 처리
```

### Step 4.2 — 2D DWT

```
- dwt53_forward_2d / dwt53_inverse_2d — 가역
- dwt97_forward_2d / dwt97_inverse_2d — 비가역
- 행 → 열 순서로 1D 적용, 다중 해상도 레벨 (재귀 LL)
```

> 1D + 2D를 `dwt.rs` 하나에 통합 구현.

**테스트**: `tests/phase4_dwt.rs`
```rust
// 1D 5/3
#[test] fn dwt53_encode_decode_4()        // 길이 4 왕복
#[test] fn dwt53_encode_decode_8()        // 길이 8 왕복
#[test] fn dwt53_encode_decode_odd()      // 홀수 길이
#[test] fn dwt53_single_sample()          // 길이 1 패스스루
#[test] fn dwt53_two_samples()            // 길이 2
#[test] fn dwt53_roundtrip_all_zeros()    // 전부 0
#[test] fn dwt53_roundtrip_length_3()     // 길이 3
#[test] fn dwt53_roundtrip_negative_values() // 음수 포함
// 1D 9/7
#[test] fn dwt97_encode_decode_8()        // 길이 8 왕복 (오차)
#[test] fn dwt97_encode_decode_odd()      // 홀수 길이
#[test] fn dwt97_precision()              // 오차 < 1e-6
// 2D
#[test] fn dwt53_2d_4x4_roundtrip()       // 4x4 왕복
#[test] fn dwt53_2d_8x8_roundtrip()       // 8x8 왕복
#[test] fn dwt53_2d_non_square()          // 직사각형 (8x4)
#[test] fn dwt53_2d_multi_level()         // 3레벨 분해/복원
#[test] fn dwt53_2d_single_level()        // 1레벨만
#[test] fn dwt53_2d_multi_level_non_power_of_two() // 비2멱 크기
#[test] fn dwt97_2d_8x8_roundtrip()       // 9/7 2D 왕복
#[test] fn dwt97_2d_multi_level()         // 9/7 다중 레벨
```

---

## Phase 5: 다중 컴포넌트 변환 (MCT)

색공간 변환 (RGB ↔ YCbCr).

### Step 5.1 — MCT (`mct.rs`)

```
- rct_forward / rct_inverse — 가역 (RCT): Y=floor((R+2G+B)/4), Cb=B-G, Cr=R-G
- ict_forward / ict_inverse — 비가역 (ICT): YCbCr 행렬
```

> DWT/MCT norm 테이블(getnorm)은 Phase 6(양자화)에서 구현.

**테스트**: `tests/phase5_mct.rs`
```rust
#[test] fn rct_encode_white()             // (255,255,255)
#[test] fn rct_encode_red()               // (255,0,0) 부호 확인
#[test] fn rct_roundtrip()                // forward→inverse 원본 복원
#[test] fn rct_roundtrip_random()         // 랜덤 데이터 왕복
#[test] fn ict_roundtrip()                // 비가역 왕복 (오차 허용)
#[test] fn ict_precision()                // 오차 < 0.5
#[test] fn mct_1000_samples()             // 대량 데이터 왕복
```

---

## Phase 6: 양자화 (Quantization)

DWT 계수를 양자화/역양자화한다.

### Step 6.1 — 양자화 (`quantize.rs`)

```
- StepSize { exponent: u8, mantissa: u16 }
- quantize_band(coeffs, stepsize, guard_bits) — 순방향
- dequantize_band(coeffs, stepsize, guard_bits) — 역방향
- calc_stepsizes(tccp, prec) — DWT norm 기반 스텝사이즈 계산
- QNTSTY_NOQNT (no quantization), QNTSTY_SIQNT (scalar implicit), QNTSTY_SEQNT (scalar explicit)
- DWT norm 테이블: dwt_getnorm(level, orient), dwt_getnorm_real(level, orient)
- MCT norm 테이블: mct_getnorm(compno), mct_getnorm_real(compno)
```

**테스트**: `tests/phase6_quantize.rs`
```rust
#[test] fn no_quantization_passthrough()  // NOQNT → 값 불변
#[test] fn scalar_quantize_dequantize()   // 양자화→역양자화 근사
#[test] fn stepsize_encode_decode()       // StepSize 바이트 표현 왕복
#[test] fn calc_stepsizes_5levels()       // 5레벨 스텝사이즈 개수 확인
#[test] fn guard_bits_effect()            // guard bits에 따른 범위
#[test] fn zero_coefficient()             // 0 계수 처리
#[test] fn dwt_norms()                    // DWT getnorm 테이블 검증
#[test] fn mct_norms()                    // MCT getnorm 테이블 검증
```

---

## Phase 7: Tier-2 코딩 및 패킷 이터레이터

패킷 헤더 파싱/조립과 진행 순서 관리.

### Step 7.1 — 패킷 이터레이터 (`pi.rs`)

```
- PiIterator { comp, res, precinct, layer, ... }
- 5가지 진행 순서: next_lrcp, next_rlcp, next_rpcl, next_pcrl, next_cprl
- pi_create(image, cp, tile_no) → PiIterator
```

**테스트**: `tests/phase7_pi.rs`
```rust
#[test] fn lrcp_order()                   // LRCP 순서 정확성
#[test] fn rlcp_order()                   // RLCP 순서 정확성
#[test] fn rpcl_order()                   // RPCL 순서 정확성
#[test] fn pcrl_order()                   // PCRL 순서 정확성
#[test] fn cprl_order()                   // CPRL 순서 정확성
#[test] fn packet_count()                 // 총 패킷 수 = L*R*C*P
#[test] fn single_tile_single_comp()      // 최소 케이스
```

### Step 7.2 — T2 패킷 인코딩/디코딩 (`t2.rs`)

```
- encode_packet(tile, comp, res, precinct, layer) → bytes
- decode_packet(bytes, tile, comp, res, precinct, layer)
- 패킷 헤더: inclusion (tgt), zero-bitplane (tgt), passes, lengths
- SOP/EPH 마커 옵션
```

**테스트**: `tests/phase7_t2.rs`
```rust
#[test] fn encode_decode_empty_packet()   // 빈 패킷 (no data)
#[test] fn encode_decode_single_cblk()    // 코드블록 1개
#[test] fn encode_decode_multi_cblk()     // 코드블록 여러개
#[test] fn sop_marker_present()           // SOP 마커 삽입 확인
#[test] fn eph_marker_present()           // EPH 마커 삽입 확인
#[test] fn inclusion_tag_tree()           // inclusion 태그트리 연동
```

---

## Phase 8: 타일 코더/디코더 (TCD)

전체 파이프라인 오케스트레이션: MCT → DWT → T1 → T2.

### Step 8.1 — TCD 구조체 및 타일 초기화 (`tcd.rs`)

```
- TcdImage, TcdTile, TcdTileComp, TcdResolution, TcdBand, TcdPrecinct, TcdCodeblock
- tcd_init(image, cp) → Tcd
- init_encode_tile / init_decode_tile
- 해상도/밴드/프리싱크/코드블록 그리드 계산
```

**테스트**: `tests/phase8_tcd.rs`
```rust
#[test] fn tile_grid_single_tile()        // 1타일 그리드
#[test] fn tile_grid_multi_tile()         // 4x4 타일 그리드
#[test] fn resolution_dimensions()        // 해상도별 크기 계산
#[test] fn band_dimensions()              // 밴드(LL,HL,LH,HH) 크기
#[test] fn precinct_count()               // 프리싱크 개수
#[test] fn codeblock_count()              // 코드블록 개수
#[test] fn codeblock_max_64x64()          // 코드블록 최대 64x64
```

### Step 8.2 — TCD 인코딩/디코딩 파이프라인 (`tcd_pipeline.rs`)

```
- encode_tile: DC shift → MCT → DWT → T1 → T2
- decode_tile: T2 → T1 → DWT → MCT → DC shift
- rate allocation (rate-distortion optimization)
```

**테스트**: `tests/phase8_tcd_pipeline.rs`
```rust
#[test] fn encode_decode_gray_tile()      // 8bit 그레이 타일 왕복
#[test] fn encode_decode_rgb_tile()       // RGB 타일 (MCT 포함) 왕복
#[test] fn lossless_gray()                // 가역 압축 → 무손실
#[test] fn lossy_psnr_threshold()         // 비가역 → PSNR > 30dB
#[test] fn rate_allocation()              // 레이트 할당 후 크기 제한
```

---

## Phase 9: J2K 코드스트림

마커 세그먼트 파싱 및 생성. 메인 헤더 + 타일 파트.

### Step 9.1 — 마커 정의 및 파서 (`marker.rs`)

```
- Marker enum (SOC=0xFF4F, SOT=0xFF90, SOD=0xFF93, EOC=0xFFD9, SIZ, COD, COC, QCD, QCC, ...)
- read_marker(stream) → Marker
- 각 마커별 read/write 함수
```

**테스트**: `tests/phase9_marker.rs`
```rust
#[test] fn parse_soc()                    // SOC 마커 인식
#[test] fn parse_eoc()                    // EOC 마커 인식
#[test] fn parse_siz()                    // SIZ: 이미지 크기, 컴포넌트 수
#[test] fn parse_cod()                    // COD: 코딩 스타일
#[test] fn parse_qcd()                    // QCD: 양자화 파라미터
#[test] fn write_read_siz_roundtrip()     // SIZ 쓰기→읽기 왕복
#[test] fn write_read_cod_roundtrip()     // COD 왕복
#[test] fn write_read_qcd_roundtrip()     // QCD 왕복
#[test] fn unknown_marker_skip()          // 알 수 없는 마커 건너뛰기
#[test] fn marker_segment_length()        // 마커 세그먼트 길이 검증
```

### Step 9.2 — J2K 코덱 (`j2k.rs`)

```
- J2kDecoder: read_header, decode_tile, decode
- J2kEncoder: setup, write_header, encode_tile, encode
- 타일 파트 관리
- POC, TLM, PLT 마커 지원
```

**테스트**: `tests/phase9_j2k.rs`
```rust
#[test] fn decode_minimal_j2k()           // 최소 J2K 스트림 디코딩
#[test] fn encode_minimal_j2k()           // 최소 J2K 스트림 인코딩
#[test] fn encode_decode_roundtrip()      // 인코딩→디코딩 왕복
#[test] fn header_parsing()               // 헤더 정보 추출
#[test] fn multi_tile_decode()            // 다중 타일 디코딩
#[test] fn specific_tile_decode()         // 특정 타일만 디코딩
#[test] fn reduce_resolution()            // 해상도 축소 디코딩
```

---

## Phase 10: JP2 파일 포맷

JP2 박스 기반 파일 포맷 래퍼. J2K 코드스트림을 감싼다.

### Step 10.1 — JP2 박스 파서 (`jp2_box.rs`)

```
- Jp2Box { box_type: u32, length: u64, data }
- 박스 타입: JP (signature), FTYP, JP2H, IHDR, COLR, JP2C, PCLR, CMAP, CDEF, RES, ...
- read_box / write_box
- read_box_header / write_box_header
```

**테스트**: `tests/phase10_jp2_box.rs`
```rust
#[test] fn read_signature_box()           // JP signature 박스
#[test] fn read_ftyp_box()                // File Type 박스
#[test] fn read_ihdr_box()                // Image Header 박스
#[test] fn read_colr_box_enum()           // Color Spec (enum)
#[test] fn read_colr_box_icc()            // Color Spec (ICC 프로필)
#[test] fn write_read_box_roundtrip()     // 박스 쓰기→읽기 왕복
#[test] fn nested_jp2h_box()              // JP2 Header 중첩 박스
#[test] fn extended_length_box()          // 확장 길이 (>2^32) 박스
```

### Step 10.2 — JP2 코덱 (`jp2.rs`)

```
- Jp2Decoder: read_header, decode → Image
- Jp2Encoder: setup, encode(Image) → bytes
- ICC 프로필 처리
- Palette (PCLR), Component Mapping (CMAP), Channel Definition (CDEF)
```

**테스트**: `tests/phase10_jp2.rs`
```rust
#[test] fn decode_minimal_jp2()           // 최소 JP2 파일 디코딩
#[test] fn encode_minimal_jp2()           // 최소 JP2 파일 인코딩
#[test] fn encode_decode_roundtrip()      // JP2 왕복
#[test] fn color_space_srgb()             // sRGB 색공간
#[test] fn color_space_grayscale()        // 그레이스케일
#[test] fn icc_profile_passthrough()      // ICC 프로필 보존
```

---

## Phase 11: Public API & 통합

사용자가 사용하는 최종 API. 파일 읽기/쓰기 통합.

### Step 11.1 — Public API (`lib.rs`)

```
- decode(reader) → Image
- encode(image, writer, params)
- Image { width, height, components: Vec<Component> }
- Component { data: Vec<i32>, width, height, precision, signed, dx, dy }
- EncodeParams { lossless, quality_layers, tile_size, ... }
```

**테스트**: `tests/phase11_api.rs`
```rust
#[test] fn decode_from_bytes()            // &[u8] → Image
#[test] fn encode_to_vec()                // Image → Vec<u8>
#[test] fn decode_j2k_format()            // J2K raw codestream
#[test] fn decode_jp2_format()            // JP2 파일 포맷
#[test] fn encode_j2k_format()            // J2K 인코딩
#[test] fn encode_jp2_format()            // JP2 인코딩
#[test] fn lossless_roundtrip_gray()      // 그레이 무손실 왕복
#[test] fn lossless_roundtrip_rgb()       // RGB 무손실 왕복
#[test] fn lossy_quality()                // 손실 압축 품질 확인
```

### Step 11.2 — 참조 호환성 테스트

openjpeg 과 동일한 입력에 대해 동일한 출력을 생성하는지 검증.

**테스트**: `tests/phase11_compat.rs`
```rust
#[test] fn compat_decode_gray_lossless()  // openjpeg 생성 파일 디코딩
#[test] fn compat_decode_rgb_lossless()   // openjpeg 생성 RGB 파일
#[test] fn compat_decode_lossy()          // openjpeg 생성 손실 파일
#[test] fn compat_multi_tile()            // 다중 타일 파일
#[test] fn compat_multi_resolution()      // 다중 해상도
```

---

## Phase 12: 확장 (선택)

### Step 12.1 — HTJ2K (Part 15) 디코더

```
- HT 블록 디코더: MEL, REV, UVLC, Forward stream
- CAP 마커 파싱
```

### Step 12.2 — 영역 지정 디코딩 (ROI)

```
- set_decode_area(x0, y0, x1, y1)
- 부분 DWT (partial decode)
```

### Step 12.3 — 멀티스레딩

```
- 타일 병렬 디코딩/인코딩
- DWT 행/열 병렬화
- T1 코드블록 병렬화
```

### Step 12.4 — SIMD 최적화

```
- DWT lifting SSE2/AVX2/NEON
- MCT SIMD
```

---

## 의존성 그래프

```
Phase 0 (types, error, stream)
  └─► Phase 1 (bio, tgt)
       └─► Phase 2 (mqc)
            └─► Phase 3 (t1)
       Phase 4 (dwt) ◄── Phase 0
       Phase 5 (mct) ◄── Phase 0
       Phase 6 (quantize) ◄── Phase 4
            └─► Phase 7 (pi, t2) ◄── Phase 1, Phase 3
                 └─► Phase 8 (tcd) ◄── Phase 3, 4, 5, 6, 7
                      └─► Phase 9 (j2k) ◄── Phase 8
                           └─► Phase 10 (jp2) ◄── Phase 9
                                └─► Phase 11 (api, compat)
                                     └─► Phase 12 (htj2k, roi, threads, simd)
```

---

## 체크리스트

| Phase | Step | 모듈 | 상태 |
|-------|------|------|------|
| 0 | 0.1 | types | ✅ |
| 0 | 0.2 | error | ✅ |
| 0 | 0.3 | stream | ✅ |
| 1 | 1.1 | bio | ✅ |
| 1 | 1.2 | tgt | ✅ |
| 2 | 2.1 | mqc_states | ✅ |
| 2 | 2.2 | mqc_enc | ✅ |
| 2 | 2.3 | mqc_dec | ✅ |
| 3 | 3.1 | t1_ctx | ✅ |
| 3 | 3.2 | t1 | ✅ |
| 4 | 4.1 | dwt_1d | ✅ |
| 4 | 4.2 | dwt_2d | ✅ |
| 5 | 5.1 | mct | ✅ |
| 6 | 6.1 | quantize | ✅ |
| 7 | 7.1 | pi | ✅ |
| 7 | 7.2 | t2 | ✅ |
| 8 | 8.1 | tcd | ✅ |
| 8 | 8.2 | tcd_pipeline | ✅ |
| 9 | 9.1 | marker | ✅ |
| 9 | 9.2 | j2k | ✅ |
| 10 | 10.1 | jp2_box | ✅ |
| 10 | 10.2 | jp2 | ✅ |
| 11 | 11.1 | api | ✅ |
| 11 | 11.2 | compat | ✅ |
| 12 | 12.1 | htj2k | ✅ (stub + CAP marker) |
| 12 | 12.2 | roi | ✅ |
| 12 | 12.3 | threads | ✅ |
| 12 | 12.4 | simd | ✅ |
