40 lines
2.4 KiB
C++
40 lines
2.4 KiB
C++
// Does the production encoder's distance-0 path succeed, and is the file lossless?
|
|
#include "fgc/JpegXlEncoder.h"
|
|
#include <jxl/decode.h>
|
|
#include <jxl/decode_cxx.h>
|
|
#include <cstdio>
|
|
#include <cstring>
|
|
#include <fstream>
|
|
#include <iterator>
|
|
#include <string>
|
|
#include <vector>
|
|
static std::vector<uint8_t> load(const char* p){std::ifstream f(p,std::ios::binary);return {std::istreambuf_iterator<char>(f),{}};}
|
|
static bool decode(const char* path, int ch, std::vector<uint8_t>& px, bool& lossy_flag){
|
|
auto data=load(path); if(data.empty()) return false;
|
|
auto dec=JxlDecoderMake(nullptr);
|
|
JxlDecoderSubscribeEvents(dec.get(), JXL_DEC_BASIC_INFO|JXL_DEC_FULL_IMAGE);
|
|
JxlDecoderSetInput(dec.get(), data.data(), data.size()); JxlDecoderCloseInput(dec.get());
|
|
JxlPixelFormat pf={(uint32_t)ch,JXL_TYPE_UINT8,JXL_NATIVE_ENDIAN,0};
|
|
for(;;){ auto s=JxlDecoderProcessInput(dec.get());
|
|
if(s==JXL_DEC_BASIC_INFO){JxlBasicInfo bi; JxlDecoderGetBasicInfo(dec.get(),&bi); lossy_flag=!bi.uses_original_profile;}
|
|
else if(s==JXL_DEC_NEED_IMAGE_OUT_BUFFER){size_t n; JxlDecoderImageOutBufferSize(dec.get(),&pf,&n); px.resize(n); JxlDecoderSetImageOutBuffer(dec.get(),&pf,px.data(),n);}
|
|
else if(s==JXL_DEC_FULL_IMAGE||s==JXL_DEC_SUCCESS) return true;
|
|
else return false; }
|
|
}
|
|
int main(){
|
|
std::ifstream j("frames/BayerRG8_0.json"); std::string t{std::istreambuf_iterator<char>(j),{}};
|
|
auto num=[&](const char* k){auto a=t.find(k); return a==std::string::npos?0:std::atoi(t.c_str()+t.find(':',a)+1);};
|
|
const int W=num("\"width\""),H=num("\"height\"");
|
|
struct T{const char* in; int ch;} ts[]={{"frames/BayerRG8_0.bin",1},{"frames/RGB8_0.bin",3}};
|
|
for(auto t:ts){
|
|
auto img=load(t.in); std::remove("check.jxl");
|
|
bool ok=fgc::JpegXlEncoder::encodeToFile("check.jxl",img.data(),W,H,t.ch,0.0f,1,3);
|
|
std::ifstream f("check.jxl",std::ios::binary|std::ios::ate); long long sz=f?(long long)f.tellg():-1;
|
|
std::vector<uint8_t> px; bool xyb=false; bool dok=sz>0&&decode("check.jxl",t.ch,px,xyb);
|
|
long long diff=0; int maxd=0;
|
|
if(dok) for(size_t i=0;i<img.size()&&i<px.size();++i){int d=std::abs(int(img[i])-int(px[i])); if(d){++diff; if(d>maxd)maxd=d;}}
|
|
std::printf("{\"input\":\"%s\",\"encode_returned\":%s,\"file_bytes\":%lld,\"decoded\":%s,\"xyb_lossy_colour\":%s,\"pixels_differing\":%lld,\"max_diff\":%d}\n",
|
|
t.in, ok?"true":"false", sz, dok?"true":"false", xyb?"true":"false", diff, maxd);
|
|
}
|
|
}
|