Skip to content

Commit

Permalink
webp image quality (0-100)
Browse files Browse the repository at this point in the history
  • Loading branch information
g-30 committed Sep 26, 2024
1 parent 48700b0 commit c47af2b
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 20 deletions.
23 changes: 17 additions & 6 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ static void print_usage()
fprintf(stdout, " -z enable temporal tta mode\n");
fprintf(stdout, " -u enable UHD mode\n");
fprintf(stderr, " -f pattern-format output image filename pattern format (%%08d.jpg/png/webp, default=ext/%%08d.png)\n");
fprintf(stderr, " -q webp image quality (0-100)\n");
fprintf(stderr, " -l list out available gpu devices\n");
}

Expand Down Expand Up @@ -190,15 +191,15 @@ static int decode_image(const path_t& imagepath, ncnn::Mat& image, int* webp)
return 0;
}

static int encode_image(const path_t& imagepath, const ncnn::Mat& image)
static int encode_image(const path_t& imagepath, const ncnn::Mat& image, float quality = 100.0)
{
int success = 0;

path_t ext = get_file_extension(imagepath);

if (ext == PATHSTR("webp") || ext == PATHSTR("WEBP"))
{
success = webp_save(imagepath.c_str(), image.w, image.h, image.elempack, (const unsigned char*)image.data);
success = webp_save(imagepath.c_str(), image.w, image.h, image.elempack, (const unsigned char*)image.data, quality);
}
else if (ext == PATHSTR("png") || ext == PATHSTR("PNG"))
{
Expand Down Expand Up @@ -370,12 +371,14 @@ class SaveThreadParams
{
public:
int verbose;
float quality;
};

void* save(void* args)
{
const SaveThreadParams* stp = (const SaveThreadParams*)args;
const int verbose = stp->verbose;
const float quality = stp->quality;

for (;;)
{
Expand All @@ -386,7 +389,7 @@ void* save(void* args)
if (v.id == -233)
break;

int ret = encode_image(v.outpath, v.outimage);
int ret = encode_image(v.outpath, v.outimage, quality);

// free input pixel data
{
Expand Down Expand Up @@ -427,7 +430,7 @@ void* save(void* args)
#if _WIN32
fwprintf(stderr, L"%ls %ls %f -> %ls done\n", v.in0path.c_str(), v.in1path.c_str(), v.timestep, v.outpath.c_str());
#else
fprintf(stderr, "%s %s %f -> %s done\n", v.in0path.c_str(), v.in1path.c_str(), v.timestep, v.outpath.c_str());
fprintf(stderr, "%s %s %f -> %s done (q - %f%)\n", v.in0path.c_str(), v.in1path.c_str(), v.timestep, v.outpath.c_str(), quality);
#endif
}
}
Expand Down Expand Up @@ -455,6 +458,7 @@ int main(int argc, char** argv)
std::vector<int> jobs_proc;
int jobs_save = 2;
int verbose = 0;
float quality = 100.0;
int tta_mode = 0;
int tta_temporal_mode = 0;
int uhd_mode = 0;
Expand All @@ -463,7 +467,7 @@ int main(int argc, char** argv)
#if _WIN32
setlocale(LC_ALL, "");
wchar_t opt;
while ((opt = getopt(argc, argv, L"0:1:i:o:n:s:m:g:j:f:vxzulh")) != (wchar_t)-1)
while ((opt = getopt(argc, argv, L"0:1:i:o:n:s:m:g:j:f:q:vxzulh")) != (wchar_t)-1)
{
switch (opt)
{
Expand Down Expand Up @@ -498,6 +502,9 @@ int main(int argc, char** argv)
case L'f':
pattern_format = optarg;
break;
case L'q':
quality = atof(optarg);
break;
case L'v':
verbose = 1;
break;
Expand Down Expand Up @@ -526,7 +533,7 @@ int main(int argc, char** argv)
}
#else // _WIN32
int opt;
while ((opt = getopt(argc, argv, "0:1:i:o:n:s:m:g:j:f:vxzulh")) != -1)
while ((opt = getopt(argc, argv, "0:1:i:o:n:s:m:g:j:f:q:vxzulh")) != -1)
{
switch (opt)
{
Expand Down Expand Up @@ -561,6 +568,9 @@ int main(int argc, char** argv)
case 'f':
pattern_format = optarg;
break;
case 'q':
quality = atof(optarg);
break;
case 'v':
verbose = 1;
break;
Expand Down Expand Up @@ -912,6 +922,7 @@ int main(int argc, char** argv)
// save image
SaveThreadParams stp;
stp.verbose = verbose;
stp.quality = quality;

std::vector<ncnn::Thread*> save_threads(jobs_save);
for (int i=0; i<jobs_save; i++)
Expand Down
54 changes: 40 additions & 14 deletions src/webp_image.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,9 @@ unsigned char* webp_load(const unsigned char* buffer, int len, int* w, int* h, i
}

#if _WIN32
int webp_save(const wchar_t* filepath, int w, int h, int c, const unsigned char* pixeldata)
int webp_save(const wchar_t* filepath, int w, int h, int c, const unsigned char* pixeldata, float quality = 100.0)
#else
int webp_save(const char* filepath, int w, int h, int c, const unsigned char* pixeldata)
int webp_save(const char* filepath, int w, int h, int c, const unsigned char* pixeldata, float quality = 100.0)
#endif
{
int ret = 0;
Expand All @@ -60,25 +60,51 @@ int webp_save(const char* filepath, int w, int h, int c, const unsigned char* pi

FILE* fp = 0;

if (c == 3)
if (quality >= 100.0)
{
// LOSSLESS
if (c == 3)
{
#if _WIN32
length = WebPEncodeLosslessBGR(pixeldata, w, h, w * 3, &output);
length = WebPEncodeLosslessBGR(pixeldata, w, h, w * 3, &output);
#else
length = WebPEncodeLosslessRGB(pixeldata, w, h, w * 3, &output);
length = WebPEncodeLosslessRGB(pixeldata, w, h, w * 3, &output);
#endif
}
else if (c == 4)
{
}
else if (c == 4)
{
#if _WIN32
length = WebPEncodeLosslessBGRA(pixeldata, w, h, w * 4, &output);
length = WebPEncodeLosslessBGRA(pixeldata, w, h, w * 4, &output);
#else
length = WebPEncodeLosslessRGBA(pixeldata, w, h, w * 4, &output);
length = WebPEncodeLosslessRGBA(pixeldata, w, h, w * 4, &output);
#endif
}
else
{
// unsupported channel type
}
else
{
// unsupported channel type
}
} else {
/// IF QUALITY IS SET
if (c == 3)
{
#if _WIN32
length = WebPEncodeBGR(pixeldata, w, h, w * 3, quality, &output);
#else
length = WebPEncodeRGB(pixeldata, w, h, w * 3, quality, &output);
#endif
}
else if (c == 4)
{
#if _WIN32
length = WebPEncodeBGRA(pixeldata, w, h, w * 4, quality, &output);
#else
length = WebPEncodeRGBA(pixeldata, w, h, w * 4, quality, &output);
#endif
}
else
{
// unsupported channel type
}
}

if (length == 0)
Expand Down

0 comments on commit c47af2b

Please sign in to comment.