int main(int argc, const char *argv[]) { WebPPicture pic1, pic2; int ret = 1; float disto[5]; size_t size1 = 0, size2 = 0; int type = 0; int c; int help = 0; int keep_alpha = 0; int scale = 0; int use_gray = 0; const char* name1 = NULL; const char* name2 = NULL; const char* output = NULL; if (!WebPPictureInit(&pic1) || !WebPPictureInit(&pic2)) { fprintf(stderr, "Can't init pictures\n"); return 1; } for (c = 1; c < argc; ++c) { if (!strcmp(argv[c], "-ssim")) { type = 1; } else if (!strcmp(argv[c], "-psnr")) { type = 0; } else if (!strcmp(argv[c], "-alpha")) { keep_alpha = 1; } else if (!strcmp(argv[c], "-scale")) { scale = 1; } else if (!strcmp(argv[c], "-gray")) { use_gray = 1; } else if (!strcmp(argv[c], "-h")) { help = 1; ret = 0; } else if (!strcmp(argv[c], "-o")) { if (++c == argc) { fprintf(stderr, "missing file name after %s option.\n", argv[c - 1]); goto End; } output = argv[c]; } else if (name1 == NULL) { name1 = argv[c]; } else { name2 = argv[c]; } } if (help || name1 == NULL || name2 == NULL) { if (!help) { fprintf(stderr, "Error: missing arguments.\n"); } Help(); goto End; } if ((size1 = ReadPicture(name1, &pic1, 1)) == 0) { goto End; } if ((size2 = ReadPicture(name2, &pic2, 1)) == 0) { goto End; } if (!keep_alpha) { WebPBlendAlpha(&pic1, 0x00000000); WebPBlendAlpha(&pic2, 0x00000000); } if (!WebPPictureDistortion(&pic1, &pic2, type, disto)) { fprintf(stderr, "Error while computing the distortion.\n"); goto End; } printf("%u %.2f %.2f %.2f %.2f %.2f\n", (unsigned int)size1, disto[4], disto[0], disto[1], disto[2], disto[3]); if (output != NULL) { uint8_t* data = NULL; size_t data_size = 0; if (pic1.use_argb != pic2.use_argb) { fprintf(stderr, "Pictures are not in the same argb format. " "Can't save the difference map.\n"); goto End; } if (pic1.use_argb) { int n; fprintf(stderr, "max differences per channel: "); for (n = 0; n < 3; ++n) { // skip the alpha channel const int range = (type == 1) ? SSIMScaleChannel((uint8_t*)pic1.argb + n, pic1.argb_stride * 4, (const uint8_t*)pic2.argb + n, pic2.argb_stride * 4, 4, pic1.width, pic1.height, scale) : DiffScaleChannel((uint8_t*)pic1.argb + n, pic1.argb_stride * 4, (const uint8_t*)pic2.argb + n, pic2.argb_stride * 4, 4, pic1.width, pic1.height, scale); if (range < 0) fprintf(stderr, "\nError computing diff map\n"); fprintf(stderr, "[%d]", range); } fprintf(stderr, "\n"); if (use_gray) ConvertToGray(&pic1); } else { fprintf(stderr, "Can only compute the difference map in ARGB format.\n"); goto End; } data_size = WebPEncodeLosslessBGRA((const uint8_t*)pic1.argb, pic1.width, pic1.height, pic1.argb_stride * 4, &data); if (data_size == 0) { fprintf(stderr, "Error during lossless encoding.\n"); goto End; } ret = ImgIoUtilWriteFile(output, data, data_size) ? 0 : 1; WebPFree(data); if (ret) goto End; } ret = 0; End: WebPPictureFree(&pic1); WebPPictureFree(&pic2); return ret; }
bool WebPEncoder::write(const Mat& img, const std::vector<int>& params) { int channels = img.channels(), depth = img.depth(); int width = img.cols, height = img.rows; const Mat *image = &img; Mat temp; size_t size = 0; bool comp_lossless = true; float quality = 100.0f; if (params.size() > 1) { if (params[0] == CV_IMWRITE_WEBP_QUALITY) { comp_lossless = false; quality = static_cast<float>(params[1]); if (quality < 1.0f) { quality = 1.0f; } if (quality > 100.0f) { comp_lossless = true; } } } uint8_t *out = NULL; if(depth != CV_8U) { return false; } if(channels == 1) { cvtColor(*image, temp, CV_GRAY2BGR); image = &temp; channels = 3; } else if (channels == 2) { return false; } if (comp_lossless) { if(channels == 3) { size = WebPEncodeLosslessBGR(image->data, width, height, image->step, &out); } else if(channels == 4) { size = WebPEncodeLosslessBGRA(image->data, width, height, image->step, &out); } } else { if(channels == 3) { size = WebPEncodeBGR(image->data, width, height, image->step, quality, &out); } else if(channels == 4) { size = WebPEncodeBGRA(image->data, width, height, image->step, quality, &out); } } if(size > 0) { if(m_buf) { m_buf->resize(size); memcpy(&(*m_buf)[0], out, size); } else { FILE *fd = fopen(m_filename.c_str(), "wb"); if(fd != NULL) { fwrite(out, size, sizeof(uint8_t), fd); fclose(fd); fd = NULL; } } } if (out != NULL) { free(out); out = NULL; } return size > 0; }
bool WebPEncoder::write(const Mat& img, const std::vector<int>& params) { CV_CheckDepthEQ(img.depth(), CV_8U, "WebP codec supports 8U images only"); const int width = img.cols, height = img.rows; bool comp_lossless = true; float quality = 100.0f; if (params.size() > 1) { if (params[0] == CV_IMWRITE_WEBP_QUALITY) { comp_lossless = false; quality = static_cast<float>(params[1]); if (quality < 1.0f) { quality = 1.0f; } if (quality > 100.0f) { comp_lossless = true; } } } int channels = img.channels(); CV_Check(channels, channels == 1 || channels == 3 || channels == 4, ""); const Mat *image = &img; Mat temp; if (channels == 1) { cvtColor(*image, temp, COLOR_GRAY2BGR); image = &temp; channels = 3; } uint8_t *out = NULL; size_t size = 0; if (comp_lossless) { if (channels == 3) { size = WebPEncodeLosslessBGR(image->ptr(), width, height, (int)image->step, &out); } else if (channels == 4) { size = WebPEncodeLosslessBGRA(image->ptr(), width, height, (int)image->step, &out); } } else { if (channels == 3) { size = WebPEncodeBGR(image->ptr(), width, height, (int)image->step, quality, &out); } else if (channels == 4) { size = WebPEncodeBGRA(image->ptr(), width, height, (int)image->step, quality, &out); } } #if WEBP_DECODER_ABI_VERSION >= 0x0206 Ptr<uint8_t> out_cleaner(out, WebPFree); #else Ptr<uint8_t> out_cleaner(out, free); #endif CV_Assert(size > 0); if (m_buf) { m_buf->resize(size); memcpy(&(*m_buf)[0], out, size); } else { FILE *fd = fopen(m_filename.c_str(), "wb"); if (fd != NULL) { fwrite(out, size, sizeof(uint8_t), fd); fclose(fd); fd = NULL; } } return size > 0; }