| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | |||||
| 3 | 4 | 5 | 6 | 7 | 8 | 9 |
| 10 | 11 | 12 | 13 | 14 | 15 | 16 |
| 17 | 18 | 19 | 20 | 21 | 22 | 23 |
| 24 | 25 | 26 | 27 | 28 | 29 | 30 |
| 31 |
- camera permission
- github 100mb
- Can't resolve
- nextjs
- github pdf
- animation
- Each child in a list should have a unique "key" prop.
- adb connect
- npm package
- camera access
- html
- react-native-dotenv
- custom printing
- vercel git lfs
- react-native
- dvh
- silent printing
- Failed to compiled
- rolldown
- 이미지 데이터 타입
- Recoil
- device in use
- ffi-napi
- adb pair
- 티스토리 성능
- electron-packager
- Git
- ELECTRON
- augmentedDevice
- github lfs
- Today
- Total
Bleeding edge
JPEG 안의 FF C0와 FF C2는 무엇일까? 본문
SOF0, SOF2, 그리고 Baseline JPEG / Progressive JPEG 쉽게 이해하기
JPEG 파일을 다루다 보면 가끔 이런 말을 보게 됩니다.
- FF C0 = SOF0 → baseline DCT
- FF C2 = SOF2 → progressive DCT
처음 보면 무슨 암호처럼 보입니다.
하지만 알고 나면, 이 값들은 JPEG 이미지가 어떤 방식으로 저장되었는지 알려주는 아주 중요한 단서입니다.
이번 글에서는 FF C0, FF C2, SOF0, SOF2, 그리고 baseline JPEG와 progressive JPEG의 차이를 쉽게 정리해보겠습니다.
JPEG 파일 안에는 “마커”가 있다
JPEG는 단순히 픽셀만 저장하는 포맷이 아닙니다.
파일 내부에는 여러 종류의 마커(marker) 가 들어 있고, 디코더는 이 마커를 읽으면서 이미지를 해석합니다.
JPEG 마커는 보통 이런 형태입니다.
FF xx
앞의 FF는 “여기서부터 마커가 시작된다”는 뜻이고,
뒤의 한 바이트 값에 따라 마커의 종류가 달라집니다.
예를 들어:
- FF D8 : SOI(Start Of Image, 이미지 시작)
- FF DA : SOS(Start Of Scan, 스캔 시작)
- FF D9 : EOI(End Of Image, 이미지 끝)
그리고 오늘의 주인공은 바로 이겁니다.
- FF C0 : SOF0
- FF C2 : SOF2
여기서 SOF는 Start Of Frame의 약자입니다.
SOF(Start Of Frame)는 뭘 의미할까?
SOF 마커는 JPEG 디코더에게
“이 이미지가 어떤 방식으로 압축되어 있는지”를 알려주는 역할을 합니다.
SOF 구간에는 이런 정보가 들어 있습니다.
- 이미지 높이와 너비
- 샘플 정밀도(보통 8-bit)
- 컬러 컴포넌트 수
- 그리고 가장 중요하게는
이 JPEG가 baseline인지 progressive인지
즉, FF C0인지 FF C2인지 보면
그 JPEG의 디코딩 방식이 거의 결정된다고 봐도 됩니다.
FF C0 = SOF0 는 무슨 뜻일까?
FF C0는 SOF0 마커입니다.
이건 곧 Baseline DCT JPEG를 뜻합니다.
정리하면:
FF C0 = SOF0 = Baseline DCT JPEG
여기서 Baseline JPEG는 우리가 가장 흔하게 접하는 일반적인 JPEG 형식입니다.
Baseline JPEG의 특징
- 가장 보편적이다
대부분의 JPEG 뷰어, 라이브러리, 하드웨어 디코더가 기본적으로 잘 지원합니다. - 디코딩이 단순하다
구조가 비교적 단순해서 빠르게 처리하기 좋습니다. - 한 번에 완성된 이미지로 디코드된다
progressive처럼 여러 번 나눠서 선명해지는 방식이 아니라, 일반적으로 최종 이미지가 바로 복원됩니다.
쉽게 말하면 Baseline JPEG는
“가장 표준적이고 범용적인 JPEG” 라고 이해하면 됩니다.
FF C2 = SOF2 는 무슨 뜻일까?
FF C2는 SOF2 마커입니다.
이건 Progressive DCT JPEG를 의미합니다.
정리하면:
FF C2 = SOF2 = Progressive DCT JPEG
Progressive JPEG의 특징
- 여러 번에 나눠서 이미지가 완성된다
처음에는 흐릿하게 전체 윤곽이 보이고,
데이터를 더 읽을수록 점점 선명해집니다. - 웹 환경에서 한때 장점이 있었다
네트워크가 느릴 때, 이미지를 위에서 아래로 천천히 보여주는 대신
“전체 그림을 먼저 흐릿하게라도 보여주고, 점점 또렷하게 만드는” 방식이 사용자 경험 측면에서 유리할 수 있었습니다. - 디코더 구현이 baseline보다 조금 더 복잡하다
여러 스캔을 조합해야 하므로 처리 경로가 더 복잡해질 수 있습니다.
즉, Progressive JPEG는
“이미지를 점진적으로 완성해 나가는 JPEG” 입니다.
Baseline JPEG와 Progressive JPEG의 차이
둘의 차이를 가장 쉽게 정리하면 이렇습니다.
Baseline JPEG
- 한 번에 디코드
- 구조가 단순
- 지원 범위가 넓음
- 일반적인 JPEG의 기본형
Progressive JPEG
- 여러 스캔을 통해 점차 선명해짐
- 구조가 더 복잡함
- 웹 로딩 경험 개선 목적으로 쓰이기도 함
- 일부 환경에서는 baseline보다 처리 경로가 까다로울 수 있음
왜 하필 FF C0, FF C2로 구분할까?
이건 JPEG 표준에서 SOF 종류마다 서로 다른 코드를 할당했기 때문입니다.
- FFC0 → SOF0 → Baseline DCT
- FFC2 → SOF2 → Progressive DCT
즉, JPEG 디코더는 파일을 읽다가 SOF 마커를 만나면
“아, 이 이미지는 baseline 방식이구나”
혹은
“이 이미지는 progressive 방식이구나”
라고 판단하게 됩니다.
실제로 확인하는 방법
리눅스나 macOS 환경이라면 JPEG 파일이 baseline인지 progressive인지 비교적 쉽게 확인할 수 있습니다.
1) file 명령어 사용
file sample.jpg
결과 예시:
sample.jpg: JPEG image data, JFIF standard 1.01, baseline, precision 8, ...
이렇게 baseline이 보이면 Baseline JPEG입니다.
반대로:
sample.jpg: JPEG image data, Exif standard, progressive, precision 8, ...
라고 나오면 Progressive JPEG입니다.
2) identify 명령어 사용
ImageMagick이 설치돼 있다면:
identify -verbose sample.jpg | grep -i Interlace
결과가
Interlace: None
이면 보통 baseline 쪽이고,
Interlace: JPEG
이면 progressive인 경우가 많습니다.
3) 바이너리에서 직접 마커 찾기
조금 더 low-level하게 보려면 파일 안에서 SOF 마커를 직접 찾을 수도 있습니다.
xxd -g 1 sample.jpg | grep -i 'ff c0\|ff c2'
- ff c0가 보이면 baseline
- ff c2가 보이면 progressive
이 방법은 JPEG가 다른 컨테이너 안에 들어 있는 경우에도 유용합니다.
예를 들어 FlatBuffer나 custom binary blob 안에 JPEG 바이트가 포함돼 있을 때도
마커를 찾아서 대략적인 판별이 가능합니다.
성능 최적화에서 왜 중요할까?
이 차이는 단순한 파일 포맷 지식으로 끝나지 않습니다.
특히 영상 처리, 하드웨어 가속, GPU 디코드, 인코딩 파이프라인 최적화 같은 영역에서는 꽤 중요합니다.
예를 들면:
- 어떤 하드웨어/라이브러리는 baseline JPEG에 최적화되어 있을 수 있음
- progressive JPEG는 별도 처리 경로가 필요할 수 있음
- decode 파이프라인을 설계할 때 baseline만 지원한다고 가정해도 되는지 먼저 확인해야 함
즉, 입력 JPEG가 baseline인지 progressive인지 아는 것은
지원 가능 여부, 성능, 구현 복잡도를 모두 좌우할 수 있습니다.
쉽게 비유해보면
두 형식을 이렇게 생각해도 됩니다.
Baseline JPEG
사진을 인화소에서 한 번에 뽑아 오는 느낌입니다.
파일을 다 읽으면 바로 최종 결과가 나옵니다.
Progressive JPEG
스케치를 먼저 보여주고,
그 위에 점점 디테일을 덧칠해 가며 완성하는 느낌입니다.
한 줄 요약
- FF C0는 SOF0, 즉 Baseline DCT JPEG
- FF C2는 SOF2, 즉 Progressive DCT JPEG
그리고 둘의 핵심 차이는:
- Baseline: 일반적인 JPEG, 단순하고 널리 지원됨
- Progressive: 여러 단계로 점점 선명해지는 JPEG
마무리
처음에는 FF C0, FF C2 같은 값이 낯설지만,
사실은 JPEG의 성격을 알려주는 아주 중요한 표식입니다.
이미지 처리 코드를 다루거나, 바이너리 포맷을 분석하거나,
하드웨어 디코더/인코더 성능을 최적화할 때
이 두 마커를 이해하고 있으면 꽤 큰 도움이 됩니다.
다음에 JPEG 바이너리를 보게 된다면,
이제 FF C0와 FF C2가 단순한 숫자가 아니라
“이 이미지가 어떤 방식으로 저장되었는지 알려주는 신호” 라는 점이 보일 겁니다.
'CS' 카테고리의 다른 글
| [Docker] 한 PC를 여러 대처럼? ipc: host 옵션으로 네트워크 경계 허물기 (1) | 2026.04.19 |
|---|---|
| 각 코덱이 생긴 이유 (0) | 2026.04.04 |
| AV1와 NVENC의 차이 (0) | 2026.04.04 |
| ROS 2에서 카메라 노드 제어: Inactive vs Subprocess (0) | 2025.09.03 |
| ROS2 DDS 환경 설정 확인하기: `ps` 명령어 활용 가이드 (0) | 2025.08.19 |