mirror of
				https://github.com/webmproject/libwebp.git
				synced 2025-10-31 18:35:41 +01:00 
			
		
		
		
	get_disto: add a '-o file' option to save a diff map
also: -scale option is useful for using the maximum range. Change-Id: I8ede7132b08ece7d3b6f699b710ab2ef3fb0b734
This commit is contained in:
		| @@ -47,6 +47,35 @@ static size_t ReadPicture(const char* const filename, WebPPicture* const pic, | ||||
|   return ok ? data_size : 0; | ||||
| } | ||||
|  | ||||
| // returns the max absolute difference | ||||
| static int DiffScaleChannel(uint8_t* src1, int stride1, | ||||
|                             const uint8_t* src2, int stride2, | ||||
|                             int x_stride, int w, int h, int do_scaling) { | ||||
|   int x, y; | ||||
|   uint32_t max = 1; | ||||
|   for (y = 0; y < h; ++y) { | ||||
|     uint8_t* const ptr1 = src1 + y * stride1; | ||||
|     const uint8_t* const ptr2 = src2 + y * stride2; | ||||
|     for (x = 0; x < w * x_stride; x += x_stride) { | ||||
|       const uint32_t diff = abs(ptr1[x] - ptr2[x]); | ||||
|       if (diff > max) max = diff; | ||||
|       ptr1[x] = diff; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   if (do_scaling) { | ||||
|     const uint32_t factor = (255u << 16) / max; | ||||
|     for (y = 0; y < h; ++y) { | ||||
|       uint8_t* const ptr1 = src1 + y * stride1; | ||||
|       for (x = 0; x < w * x_stride; x += x_stride) { | ||||
|         const uint32_t diff = (ptr1[x] * factor) >> 16; | ||||
|         ptr1[x] = diff; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|   return max; | ||||
| } | ||||
|  | ||||
| static void Help(void) { | ||||
|   fprintf(stderr, | ||||
|           "Usage: get_disto [-ssim][-psnr][-alpha] compressed.webp orig.webp\n" | ||||
| @@ -54,6 +83,8 @@ static void Help(void) { | ||||
|           "  -psnr ..... print PSNR distortion (default)\n" | ||||
|           "  -alpha .... preserve alpha plane\n" | ||||
|           "  -h ........ this message\n" | ||||
|           "  -o <file> . save the diff map as a WebP lossless file\n" | ||||
|           "  -scale .... scale the difference map to fit [0..255] range\n" | ||||
|           " Also handles PNG, JPG and TIFF files, in addition to WebP.\n"); | ||||
| } | ||||
|  | ||||
| @@ -66,8 +97,10 @@ int main(int argc, const char *argv[]) { | ||||
|   int c; | ||||
|   int help = 0; | ||||
|   int keep_alpha = 0; | ||||
|   int scale = 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"); | ||||
| @@ -81,9 +114,17 @@ int main(int argc, const char *argv[]) { | ||||
|       type = 0; | ||||
|     } else if (!strcmp(argv[c], "-alpha")) { | ||||
|       keep_alpha = 1; | ||||
|     } else if (!strcmp(argv[c], "-scale")) { | ||||
|       scale = 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 { | ||||
| @@ -115,6 +156,43 @@ int main(int argc, const char *argv[]) { | ||||
|   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 != pic1.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 absolute differences per channel: "); | ||||
|       for (n = 0; n < 3; ++n) {    // skip the alpha channel | ||||
|         const int range = 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); | ||||
|         fprintf(stderr, "[%d]", range); | ||||
|       } | ||||
|       fprintf(stderr, "\n"); | ||||
|     } 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: | ||||
|   | ||||
		Reference in New Issue
	
	Block a user