2P by GN⁺ | ★ favorite | 댓글 2개
  • 큰 이미지를 한 번에 처리하던 JPEG XL 인코딩의 병목을 libjxl 0.10이 스트리밍 인코딩 API로 줄이며, 무손실 압축의 메모리 사용량과 속도를 크게 개선함
  • 13500×6750 NASA 야간 지구 이미지 무손실 인코딩은 libjxl 0.9의 약 8GB RAM·2분 이상에서 libjxl 0.10의 0.7GB RAM, 단일 스레드 30초, 8스레드 5초로 줄어듦
  • 압축 방식 비교는 파일 크기만으로 부족하며, 인코딩 속도와 압축 밀도를 함께 보는 파레토 프론트가 시간 예산별 최적 설정을 가르는 기준이 됨
  • 손실 압축은 압축률·속도·화질을 동시에 봐야 하며, SSIMULACRA2 60~90 범위에서 JPEG XL은 특히 고화질~시각적 무손실 영역에서 강한 결과를 보임
  • jpegli 같은 새 JPEG 인코더도 매우 빠른 인코딩 구간에서는 여전히 경쟁력이 있지만, JPEG XL은 넓은 속도 범위에서 무손실·손실 압축 모두의 핵심 선택지로 자리 잡음

libjxl 0.10의 핵심 변화

  • libjxl 0.10은 JPEG XL 참조 구현의 새 버전이며, 가장 큰 변화는 스트리밍 인코딩 API의 완전 구현임
  • 이 API는 큰 이미지를 한 번에 처리하지 않고 청크 단위로 인코딩함
    • 전체 이미지를 메모리에 올릴 때 생기는 RAM 부담이 줄어듦
    • 인코딩 속도도 함께 개선됨
    • 특히 큰 이미지의 무손실 압축에서 효과가 두드러짐

무손실 압축에서 줄어든 메모리와 시간

  • libjxl 0.10 이전의 무손실 JPEG XL 인코딩은 큰 메모리와 긴 처리 시간이 문제가 될 수 있었음
  • 예시 이미지는 NASA의 13500×6750 야간 지구 이미지
    • TIFF 파일은 64MB
    • 압축 전 크기는 273MB
  • 기본 effort 설정 e7에서 같은 이미지를 압축한 결과:
    • libjxl 0.9는 약 8GB RAM을 사용하고 2분 이상 걸렸으며, 결과 파일은 33.7MB였음
    • 단일 스레드는 2분 40초, 8스레드는 2분 6초로 스레드 증가 효과가 크지 않았음
    • 측정 환경은 12코어 Apple M3 Pro CPU와 36GB RAM을 탑재한 2023년 11월 MacBook Pro임
  • libjxl 0.10에서는 같은 이미지 압축에 0.7GB RAM만 필요함
    • 단일 스레드 30초
    • 8스레드 5초
    • 결과 파일은 33.2MB
  • effort 값을 높이면 압축률은 좋아지지만 CPU 시간 대비 개선 폭은 점점 줄어듦
    • e1에서 e2로 가며 0.1초 대신 1초를 쓰면 22MB를 줄일 수 있었음
    • e2에서 e7로 가며 1초 대신 5초를 쓰면 추가로 11MB를 줄였음
    • e7에서 e9로 가며 1MB를 더 줄이려면 거의 2분을 기다려야 했음

effort 설정의 실용적 절충

  • 압축 설정은 시간과 파일 크기 사이의 절충 문제임
  • 이미지 편집 중 로컬에 저장하는 저작 워크플로에서는 강한 압축이 꼭 필요하지 않아 낮은 effort 인코딩이 합리적일 수 있음
  • 일대다 전달 시나리오나 장기 보관에서는 CPU 시간을 더 써서 몇 MB를 줄이는 선택이 가치 있을 수 있음

파레토 프론트로 압축 방식 비교하기

  • 압축 기법을 비교할 때 파일 크기만 보면 실제 선택에 필요한 정보를 놓치기 쉬움
  • 비교 축과 차트 해석

    • 핵심 축은 압축 밀도인코딩 속도
    • 어떤 방식이 파레토 최적이라는 것은, 같은 또는 더 나은 압축 밀도를 더 짧은 시간에 달성하는 다른 방식이 없다는 뜻임
    • 파레토 최적 방식들의 집합이 파레토 프론트
    • 차트에서는 세로축이 인코딩 속도, 가로축이 압축된 이미지의 평균 bits per pixel임
    • 세로축은 megapixels per second 단위이며, 폭넓은 속도 범위를 다루기 위해 로그 스케일을 사용함
    • 압축 전 8비트 RGB는 24bpp임
    • 위쪽일수록 빠르고, 왼쪽일수록 압축률이 좋음

무손실 압축 비교 결과

  • 이전 libjxl도 모든 속도 범위에서 파레토 최적 결과를 냈고, PNG·무손실 AVIF·무손실 WebP보다 작은 파일을 만들었음
  • libjxl 0.10은 이전 버전보다 상당한 차이로 더 나은 결과를 보임
  • QOI는 차트에는 표시되지 않았지만, 154Mpx/s에서 17bpp를 기록함
    • libjxl의 가장 낮은 effort 설정은 427Mpx/s에서 11.5bpp까지 압축함
    • libjxl 쪽이 2.7배 빠르고 결과 파일은 32.5% 작았음

비사진 이미지에서의 무손실 압축

  • 사진은 자연 노이즈가 많아 무손실 압축이 어려운 편이며, 비사진 이미지에서는 결과가 달라짐
  • 다양한 그림체의 만화 이미지 41장을 사용한 테스트에서 평균 크기는 7.3메가픽셀이었음
  • 이런 이미지는 약 4bpp까지 압축되어, 사진 이미지의 약 10bpp보다 훨씬 잘 압축됨
  • 무손실 AVIF는 이 이미지 유형에서 유용하지 않았음
    • PNG보다 압축률이 낮았음
    • QOI와 비슷한 밀도에 도달했지만 훨씬 느렸음
  • 무손실 WebP는 이런 이미지에서 매우 좋은 압축률을 보임
  • QOI는 속도와 단순성을 고려하면 괜찮지만 파레토 최적과는 거리가 있음
    • 낮은 effort의 JPEG XL 인코딩은 QOI보다 2배 빠르고 31% 작았음
  • libjxl 0.10은 비사진 이미지에서도 0.9보다 크게 개선됨
    • WebP 기본 effort는 4.30bpp, 2.3Mpx/s
    • libjxl 0.9 effort 5는 4.27bpp, 2.6Mpx/s
    • libjxl 0.10 effort 5는 4.25bpp, 12.2Mpx/s
    • libjxl 0.10 effort 7은 4.04bpp, 5.9Mpx/s

손실 압축에는 화질 축이 추가됨

  • 무손실 압축은 압축 크기와 속도만 보면 되지만, 손실 압축에는 화질이 추가됨
  • 손실 이미지 코덱과 인코더는 품질 지점에 따라 성능이 달라질 수 있음
    • 고화질 인코딩에서 좋은 인코더가 저화질에서도 좋다고 볼 수 없음
    • 반대도 마찬가지임
  • 압축률과 화질만 보는 bitrate-distortion 플롯은 인코딩 effort와 압축 성능 사이의 절충을 평가하기 어렵게 함
  • 손실 압축의 파레토 프론트를 보려면 압축·속도·화질의 3차원 공간을 여러 품질 지점에서 잘라 봐야 함

화질 측정과 집계 방식

  • 이미지 화질은 주관적이며 사람마다 다를 수 있음
  • 가장 좋은 측정 방식은 수십 명 이상의 사람이 엄격한 테스트 프로토콜에 따라 이미지를 비교하거나 점수화하는 실험임
  • 이런 실험은 시간과 비용이 많이 들어 모든 인코더 설정을 테스트하기 어렵기 때문에 객관 지표가 쓰임
  • 공개 지표 중 좋은 지표로는 SSIMULACRA2, Butteraugli, DSSIM이 꼽힘
    • 이들은 인간 시각 시스템을 모델링하려고 하며 주관 평가와의 상관이 좋음
    • PSNR이나 SSIM 같은 오래된 단순 지표는 인간의 화질 판단과 잘 맞지 않음
  • 인코더가 내부적으로 최적화하는 지표로 평가하면 결과가 해당 인코더에 유리하게 왜곡될 수 있음
    • 고 effort libjxl은 Butteraugli를 최적화함
    • libavif는 PSNR 또는 SSIM을 최적화할 수 있음
    • SSIMULACRA2는 테스트된 인코더가 내부 최적화에 쓰지 않아 안전한 지표로 취급됨
  • 테스트에서는 각 설정을 전체 이미지 집합에 적용했을 때 평균 SSIMULACRA2 점수가 특정 값에 가깝도록 인코더 설정을 선택함
  • 평균 점수 정렬은 WebP와 AVIF에 유리한 방식임
    • 이전 연구에서는 AVIF와 WebP가 JPEG·HEIC보다 일관성이 낮고, JPEG XL은 가장 일관적인 인코더였음
    • 실사용에서는 최악의 점수 또는 실제 최악의 시각 품질을 맞추고 싶을 수 있음

실제 사용에 가까운 품질 범위

  • 손실 압축은 50:1이나 200:1 같은 높은 압축률도 가능하지만, 압축 아티팩트가 생김
  • 실제 사용에서 관련성이 큰 범위는 SSIMULACRA2 60~90
  • 품질 지점별 특성:
    • SSIMULACRA2 90: 시각적 무손실 품질이며, AVIF와 JPEG XL 같은 현대 코덱은 약 8:1 압축률, 즉 3bpp로 도달할 수 있음
    • SSIMULACRA2 80: 고화질이며, 약 16:1 압축률, 즉 1.5bpp로 도달할 수 있음
    • SSIMULACRA2 70: 중상 품질이며, 약 30:1 압축률, 즉 0.8bpp로 도달할 수 있음
    • SSIMULACRA2 60: 중간 품질이며, 약 40:1 압축률, 즉 0.6bpp로 도달할 수 있음
  • SSIMULACRA2 60보다 낮은 품질은 대역폭을 더 줄일 수 있지만 이미지를 망칠 위험이 있음
  • 2024년 웹에서는 중간~고화질 범위가 관련성이 큼
    • HTTP Archive 기준 웹의 AVIF 중앙값은 1bpp로, 중상 품질에 해당함
    • JPEG 중앙값은 2.1bpp로, 고화질에 해당함
  • 카메라 같은 비웹 사용 사례에서는 고화질~시각적 무손실 범위가 더 관련 있음

손실 압축 파레토 프론트 결과

  • 손실 압축 테스트는 2024년 2월 말 기준 각 인코더의 최신 버전으로 수행됨
  • 인코딩 속도는 Apple M3 Pro 기반 2023년 11월 MacBook Pro에서 8스레드로 측정됨
  • AVIF는 타일 설정과 비타일 설정을 모두 테스트함
    • 타일 설정은 멀티스레딩 활용이 좋아 더 빠름
    • 대신 압축 밀도 손실이 있음

중간 품질: SSIMULACRA2 60

  • 같은 포맷 안에서도 인코더와 effort 설정에 따라 결과 차이가 컸음
  • 역사적으로 널리 쓰인 JPEG 인코더인 libjpeg-turbo 기본 설정은 차트에서 가장 빠르지만 압축 밀도가 낮은 쪽에 위치함
  • WebP는 libjpeg-turbo보다 압축 밀도가 좋았음
  • mozjpeg는 libjpeg-turbo보다 느리지만 더 나은 압축 결과를 제공하며, 이 이미지 집합과 품질 지점에서는 WebP보다 파레토 효율적이었음
  • Google의 JPEG XL 팀이 만든 jpegli는 mozjpeg보다 빠르고 압축률도 좋았음
    • guetzli와 libjxl에서 얻은 교훈을 기반으로 함
    • WebP와 고속 AVIF보다 더 잘 압축하면서도 기존 JPEG 파일을 생성함
  • AVIF와 HEIC는 JPEG·WebP보다 나은 압축 밀도를 얻을 수 있지만 인코딩은 더 느렸음
  • JPEG XL은 비슷한 압축 밀도에 도달하면서 훨씬 빠르게 인코딩함
  • 이 품질 지점의 파레토 프론트는 합리적인 속도 구간에서는 JPEG XL과 여러 JPEG 인코더, 더 느린 구간에서는 AVIF로 구성됨

중상·고화질 결과

  • SSIMULACRA2 70의 중상 품질에서는 전체 결과가 중간 품질과 비슷했음
  • 웹에 관련된 가장 높은 품질 지점으로 평균 SSIMULACRA2 85를 사용했으며, 대부분의 이미지가 80 이상을 달성하도록 설정함
  • 이 고화질 지점에서는 차이가 더 뚜렷해짐
    • mozjpeg는 더 이상 WebP를 이기지 못했음
    • jpegli는 여전히 WebP를 이겼음
    • 파레토 프론트는 대부분 JPEG XL이 차지했음
    • 매우 빠른 인코딩에서는 기존 JPEG가 여전히 좋았음
  • 이 품질 지점에서 AVIF는 파레토 프론트에 없었음
    • 가장 느린 설정에서 0.5Mpx/s 이하 속도로 두 번째로 빠른 libjxl 설정과 같은 압축 밀도를 맞췄음
    • 해당 libjxl 설정은 52Mpx/s로 100배 이상 빨랐음

디코딩 속도

  • 지금까지의 비교는 압축 밀도와 인코딩 속도 중심이었음
  • 현대 컴퓨터에서 디코딩 속도는 큰 문제가 아니지만 측정값도 비교됨
  • 순차 JPEG는 디코딩 속도에서 가장 강함
  • mozjpeg와 기본 jpegli가 생성하는 프로그레시브 JPEG는 더 느리지만, 합리적인 크기의 이미지를 매우 빠르게 로드할 만큼 충분히 빠름
  • JPEG XL은 순차 JPEG와 프로그레시브 JPEG 사이에 위치함
  • AVIF의 디코딩 속도는 인코딩 방식에 따라 달라짐
    • 더 빠르지만 약간 나쁜 멀티타일 인코딩을 사용하면 디코딩도 더 빠름
    • 기본 싱글타일 인코딩은 더 느림
  • 측정된 가장 느린 디코딩 속도도 인코딩 속도와 비교하면 충분히 빠른 편임

시각적 무손실과 큰 이미지

  • 시각적 무손실 품질 차트에는 WebP가 포함되지 않았음
    • 손실 모드에서 이 품질 지점에 도달할 수 없었음
    • WebP는 4:2:0 크로마 서브샘플링이 의무적이기 때문임
  • mozjpeg도 이 품질 지점에 맞게 설계되지 않아 libjpeg-turbo보다 압축과 속도 모두 나빴음
  • 기본 속도 설정에서 libavif는 libjpeg-turbo보다 20% 작았지만 인코딩에는 한 자릿수 더 긴 시간이 걸렸음
  • 같은 품질 지점에서 libjxl은 libavif보다 20% 작고 2.5배 빨랐음
  • 시각적 무손실 품질의 파레토 프론트는 대부분 JPEG XL이 차지했으며, 가장 빠른 속도 구간에는 JPEG도 포함됨
  • 웹 크기 이미지 약 1메가픽셀 테스트와 달리, 더 큰 이미지 테스트에서는 결과가 크게 달라짐
    • 고화질 지점에서 WebP, mozjpeg, AVIF는 libjpeg-turbo보다 나빴음
    • HEIC는 libjpeg-turbo 대비 상당한 절감을 제공함
    • jpegli도 더 나은 속도로 상당한 절감을 제공함
    • JPEG XL은 이미지를 1.3bpp 미만으로 압축했고, AVIF·libjpeg-turbo·WebP는 2bpp 이상이 필요했음

libjxl 0.10의 최종 위치

  • libjxl 0.10은 무손실·손실 압축 모두에서 메모리 사용량을 한 자릿수 규모로 줄임
  • 속도도 개선됐으며, 특히 멀티스레드 무손실 인코딩의 기본 effort 설정은 한 자릿수 규모로 빨라짐
  • JPEG XL은 무손실과 손실 압축 모두에서, 특히 고화질~시각적 무손실 품질 범위에서 강한 이미지 코덱으로 정리됨
  • 넓은 속도 설정 범위에서 JPEG XL은 파레토 최적에 가까운 선택지로 남아 있음
  • 기존 JPEG도 새 인코더 덕분에 여전히 매력적임
    • jpegli는 mozjpeg보다 속도와 압축 모두에서 크게 개선됨
    • 극도로 빠른 인코딩이 필요할 때 기존 JPEG는 여전히 최선의 선택일 수 있음

댓글과 토론

jpegli 인코더가 mozjpeg에 이어 또다시 jpg를 생명연장 시키네요...
JXL 진영에서 만들었으나 아이러니하게도 JXL의 전파를 저해할지도 모르겠네요...

Hacker News 의견들
  • 무손실 WebP가 얼마나 좋은지도 주목해야 함
    WebP가 MozJPEG 인코딩 대비 확실한 이점이 부족하거나 더 나쁘다는 얘기에 많이 묻히지만, 무손실 WebP는 성능과 속도 면에서 정말 훌륭함
    PNG나 OptiPNG보다 훨씬 낫고, 온라인 지원도 충분해졌으며, 형편없는 무손실 AVIF도 당연히 크게 앞섬

    • 무손실 WebP는 정말 좋지만, 8비트만 지원해서 미래 대비가 약함
      SDR 이미지에는 괜찮지만 HDR에는 GIF가 256색으로 제한되는 것만큼 근본적인 한계가 됨
    • 무손실 WebP는 (A)RGB만 지원하고, 그레이스케일은 단색 지원보다 못한 우회 방식으로 인코딩한다는 문제가 있음
      만화 전체를 압축한다면 PNG가 여전히 맞고, 이때는 사실상 폐기된 optipng보다 oxipng를 쓰는 편이 좋음
      또 여기서 빠진 점으로, 무손실 JPEG2000은 사진 콘텐츠에서 의외로 좋고 빠를 수 있음
    • WebP에는 무손실 WebP 명세 기반의 거의 무손실 인코딩 모드도 있는데 거의 홍보되지 않음
      실제 무손실보다 대부분의 용도에서 선호할 만하고, 추가로 눈에 보이는 손실 없이 크기를 절반으로 줄이는 경우가 많음
    • 새 이미지 포맷인 AVIF와 HEIC의 무손실 버전이 오래된 PNG에 비해 이렇게 성능이 안 좋은 게 꽤 충격적임
    • 무손실 AVIF에서도 추가 절감 여지가 있어 보임: https://www.reddit.com/r/AV1/comments/1b3lh08/comment/kstmbr...
  • 매우 낮은 품질 설정에서는 JPEG가 눈에 띄는 아티팩트 때문에 가까이서 보면 입체파 그림처럼 엉망이어도, 이미지의 전체 품질을 더 잘 보존하는 선명한 디테일 근사를 유지하는 점이 놀라움
    사실상 이미지를 어떤 추상 미술 스타일로 바꾸는 셈인데, JXL과 AVIF는 그냥 흐릿해짐

    • 그건 JPEG에는 픽셀당 0.5비트가 주어지고, JPEG XL과 AVIF에는 약 0.22와 0.2비트만 주어졌기 때문임
      이 이미지들은 같은 압축률이 아니라 같은 왜곡 수준을 맞추려는 것이고, 픽셀당 비트 수는 이미지 옆에 표시되어 있음
      실제 인터넷에서 품질 65 사용은 드물고 최저 품질 사이트에서나 쓰이며, 품질 75가 흔한 저품질, 품질 85가 평균에 가까움
      압축이 필요할 때는 품질 94 yuv444 이상을 사용함
    • 이 이미지를 말하는 거라면 https://res.cloudinary.com/jon/qp-low.png
      비트레이트는 왼쪽 열에 있고, 저품질 JPG는 JXL/AVIF의 중하 품질인 0.4bpp와 같은 크기라서 왼쪽 아래 그림을 위쪽 가운데와 오른쪽 그림과 비교해야 함
    • JPEG는 여전히 픽셀당 약 두 배 많은 비트를 쓰기 때문에 결과 파일 크기가 훨씬 큼
      잘못된 비교에 휩쓸리면 안 되고, JXL과 AVIF도 파일 크기를 두 배로 주면 훨씬 좋아 보임
    • JPEG 비트레이트가 더 높으므로, 이 테스트에서는 SSIMULACRA2가 잘못된 지표라는 뜻에 가까움
      SSIMULACRA2는 블록 아티팩트를 강하게 벌주지만 흐림에는 별로 신경 쓰지 않는 것 같고, 같은 SSIMULACRA2 점수라면 JPEG 버전이 더 좋아 보인다는 데 동의함
    • 이 글에서 얻은 결론도 JPEG가 속눈썹 같은 가장자리 선명도를 정말 잘 유지하는 반면, JXL과 AVIF는 이미지의 모든 디테일을 매끈하게 뭉갠다는 것이었음
  • 이 글이 왜 인코딩 속도에는 그렇게 집중하면서, 웹 연결 환경에서 사용량의 99%에 해당한다고 보는 디코딩은 대충 다루는지 이해가 안 됨
    “디코딩 속도는 현대 컴퓨터에서 큰 문제가 아니지만, 수치를 빠르게 보는 것은 흥미롭다” 정도로 넘어감

    • 초당 100MB를 넘으면 인터넷에서는 충분하다고 봄
      그 시점부터 병목은 더 이상 디코딩이 아니기 때문임
      현대 압축 알고리즘 대부분은 비대칭이라 압축에는 훨씬 많은 시간을 써도 압축 해제 성능에는 큰 영향을 주지 않으므로, 기본 성능만 달성하면 덜 중요해짐
    • AVIF/AV1이나 HEIC/H264처럼 동영상 포맷에서 파생된 이미지 포맷을 하드웨어 동영상 디코더로 디코딩하는 게 실용적인지 궁금함
      가능하다면 현재 하드웨어에서 모두 소프트웨어로 디코딩해야 하는 JPEG XL보다 이들을 선호할 강력한 이유가 될 수 있음
      H264 디코딩은 어디에나 있고, AV1 디코딩도 꾸준히 표준 기능이 되어가는 중임
    • 어떤 용도에서는 회사가 인코딩 비용을 내고, 클라이언트가 디코딩을 수행함
      클라이언트가 페이지의 몇 장 안 되는 이미지를 사람이 못 느낄 만큼 빠르게 디코딩할 수 있으면 충분하고, 반대로 인코딩에서 몇 퍼센트라도 개선되면 실제 비용을 절감할 수 있음
    • 실시간 인코딩은 꽤 흔해서 인코딩 속도가 중요함
    • 그게 Cloudinary의 사용 사례이기 때문임
      실제로 이미지 인코딩에 수백만 달러를 씀
  • 무손실 벤치마크에 QOI가 들어간 걸 보고 웃음이 났음
    일반 대중용 소프트웨어에서 기본 지원되지 않고, 좋기보다는 그냥 괜찮은 정도를 목표로 하는 사실상 무관한 포맷인데도, 비사진 인코딩 차트 한 자리를 차지했다는 점이 흥미로움

    • GameMaker Studio는 꽤 빠르게 QOI 흐름에 올라탔고, 2년 전 PNG 텍스처를 QOI로 바꾸고 그 위에 BZ2 압축을 더해 평균 20% 크기 감소를 얻었음
      그래서 GameMaker Studio와 최근 2년쯤 만들어진 게임들은 실제로 내부에서 QOI를 사용함
      소비자가 의식적으로 쓰는 건 아니지만, 완전히 무관하다고 보기도 어려움
    • 그래도 파레토 프런티어에는 닿지 못했음
      돌이켜보면 당연한데, QOI 디코딩은 본질적으로 순차적이라 쉽게 병렬화할 수 없음
  • JXL의 훌륭함이 포맷 자체 덕분인지 인코더 덕분인지 궁금함
    -d 1.0만으로 고품질의 작은 이미지를 만드는 능력은 기묘할 정도이고, 다른 코덱에서는 비슷한 결과를 얻으려면 이미지 유형에 따라 품질 설정을 다르게 줘야 했음

    • 아주 좋은 지점임
      이 개발 속도라면 libjxl이 이미지 인코더계의 x264가 되어도 놀랍지 않음
      반대로 libvpx는 늘 평범한 인코더였고, 그게 vp8/vp9 포맷의 실망스러운 성능, 속도뿐 아니라 전반적 성능의 원인일 수 있다고 봄
      이는 필연적으로 손실 WebP 성능에도 영향을 줬고, Dark Shikari가 x264와 vp8의 정지 이미지 성능도 비교한 적이 있음 [0]
      [0] https://web.archive.org/web/20150419071902/http://x264dev.mu...
    • Pik는 처음에 품질 옵션 없이 거리 1.0에서 가능한 최선을 달성하도록 설계됐음
      시각적 무손실에 많은 초점을 유지했고, 높은 품질 설정에 도움이 되지 않으면서 복잡도만 늘리는 포맷 기능은 넣고 싶지 않았음
      모델링 기능 외에도 문맥 모델링과 엔트로피 부호화 효율이 고품질에서 매우 중요함
      AVIF의 엔트로피 부호화는 고품질 또는 무손실 사진에는 잘 맞지 않는다고 봄
    • 같은 -d 1.0 인터페이스를 가진 JPEG 인코더 cjpegli도 만들었음
  • JPEG XL 작업에서 Highway라는 훌륭한 새 병렬화 라이브러리도 나왔다는 점은 언급할 만함
    이 라이브러리는 JPEG XL뿐 아니라 Google의 최신 Gemma AI 모델에도 쓰이고 있음

    • Highway에 관심 있다면 [0]을 보면 됨
      [1]에서도 다루는데, 시작은 이렇다: “오늘 우리는 숫자 배열을 C++ std::sort보다 약 10배 빠르게 정렬하고, 모든 현대 CPU 아키텍처에서 이식성을 유지하면서도 최신 아키텍처별 알고리즘보다 빠른 오픈 소스 코드를 공유합니다. 아래에서 이를 어떻게 달성했는지 논의합니다.”
      [0] https://github.com/google/highway
      [1] https://opensource.googleblog.com/2022/06/Vectorized%20and%2..., 관련 논문은 https://arxiv.org/pdf/2205.05982.pdf
    • 그리고 VIPS도 있음
      C++에서 이식 가능한 SIMD를 얻는 가장 좋은 방법처럼 보임
  • JPEG XL이 자체적으로 얼마나 빛나는지와 별개로, 다음을 할 수 있다는 점만으로도 확실히 대단함
    a.jpg는 615504바이트이고 SHA-1은 716744d950ecf9e5757c565041143775a810e10f
    cjxl a.jpg a.jxl을 실행하면 615504바이트 JPEG를 읽어 컨테이너 포함 537339바이트로 압축함
    그런데 djxl a.jxl b.jpg를 실행하면 537339바이트 압축 데이터를 읽고 JPEG로 재구성하며, b.jpg도 615504바이트에 SHA-1이 완전히 같음
    보존하고 싶은 JPEG 파일이 세상에 수십억 개 있다는 점을 생각해보면, 기존 JPEG를 손실 포맷으로 재압축하면 품질이 낮아짐
    하지만 JPEG XL은 15~30%를 절약하면서도 원한다면 원래 JPG를 비트 단위로 100% 동일하게 되돌릴 수 있음
    정말 멋짐
    안타깝게도 Debian stable 12 Bookworm을 쓰고 있는데 ImageMagick 6.9이고, Emacs가 이미지를 표시할 때 아마 ImageMagick을 쓰는 것으로 앎
    JPEG XL 지원은 ImageMagick 7에야 추가됐고, 아직 더 파보지는 못했음

    • 그 요구사항을 JPEG XL에 넣는 데 기여했음
      손실 재인코딩 없이 디지털 유산을 온전히 보존하는 데 도움이 될 거라고 봄
    • JPEG를 스크린샷으로 찍어서 WhatsApp으로 다시 보내는 사용자들에게 엄청 소중하게 여겨질 기능이겠음 :P
  • libjxl 새 버전이 손실·무손실 압축 모두에서 메모리 사용량을 한 자릿수 규모로 줄였고, 속도도 개선됐다는 점이 매우 인상적임
    특히 다중 스레드 무손실 인코딩의 기본 노력 설정이 이제 한 자릿수 규모로 더 빨라졌다는 부분이 좋고, 글도 잘 쓰였음

  • JPEG XL 포맷의 각 단계를 자세히 설명하는 웹사이트가 있는지 궁금함
    전통적인 JPEG와 달리 관련 단계를 명확히 안내하는 문서를 찾기 어려웠고, 이 포맷에는 흥미로운 혁신이 많이 모여 있는 것이 분명해서 아쉬움
    개별 구성요소들도 그 자체로 유용할 것 같음

  • 글에는 AV1, 따라서 AVIF를 인코딩하는 rav1e가 빠져 있음
    rav1e는 참조 구현인 aom보다 훨씬 빠르고, aom이 1분을 기다려도 이미지 변환을 끝내지 못한 반면 rav1e는 10초도 안 걸린 경우가 있었음

    • rav1e의 파레토 곡선이 libaom의 파레토 곡선보다 앞서는지 궁금함
      빠른 rav1e가 높은 인코딩 속도에서 jpegli보다 좋아 보이는지도 궁금함
    • rav1e와 libaom 모두 속도 설정이 있음
      비슷한 속도에서는 둘 사이에 압축 성능 차이가 크게 나는 것을 보지 못했음