Exemplo n.º 1
0
static size_t encode(const uint8_t* rgba, int width, int height,
                     uint8_t** output)
{
    WebPPicture pic;
    WebPConfig config;
    WebPMemoryWriter wrt;
    int ok;

    if (!WebPConfigPreset(&config, WEBP_PRESET_DEFAULT, 100) ||
            !WebPPictureInit(&pic))
    {
        return 0;
    }

    config.lossless = true;
    config.method = 6;
    pic.use_argb = true;
    pic.width = width;
    pic.height = height;
    pic.writer = WebPMemoryWrite;
    pic.custom_ptr = &wrt;
    WebPMemoryWriterInit(&wrt);

    ok = WebPPictureImportRGBA(&pic, rgba, width * 4) &&
         WebPEncode(&config, &pic);
    WebPPictureFree(&pic);
    if (!ok)
        return 0;
    *output = wrt.mem;
    return wrt.size;
}
Exemplo n.º 2
0
static gboolean
export_webp (GeglOperation       *operation,
             GeglBuffer          *input,
             const GeglRectangle *result,
             GOutputStream       *stream)
{
  GeglProperties *o = GEGL_PROPERTIES (operation);
  WebPConfig config;
  WebPPicture picture;
  const Babl *format;
  gint status;

  g_return_val_if_fail (stream != NULL, FALSE);

  if (!WebPConfigInit (&config) || !WebPPictureInit (&picture))
    {
      g_warning ("could not initialize WebP encoder");
      return FALSE;
    }

  if (!WebPConfigPreset (&config, WEBP_PRESET_DEFAULT, o->quality))
    {
      g_warning("could not load WebP default preset");
      return FALSE;
    }

  picture.width = result->width;
  picture.height = result->height;

  format = babl_format ("R'G'B'A u8");

  if (!WebPValidateConfig (&config))
    {
      g_warning ("WebP encoder configuration is invalid");
      return FALSE;
    }

  picture.writer = write_to_stream;
  picture.custom_ptr = stream;

  if (save_RGBA (&picture, input, result, format))
    {
      g_warning ("could not pass pixels data to WebP encoder");
      return FALSE;
    }

  status = WebPEncode (&config, &picture);

  WebPPictureFree (&picture);

  return status ? TRUE : FALSE;
}
static gboolean
gst_webp_enc_start (GstVideoEncoder * benc)
{
  GstWebpEnc *enc = (GstWebpEnc *) benc;

  if (!WebPConfigPreset (&enc->webp_config, enc->preset, enc->quality)) {
    GST_ERROR_OBJECT (enc, "Failed to Initialize WebPConfig ");
    return FALSE;
  }

  enc->webp_config.lossless = enc->lossless;
  enc->webp_config.method = enc->speed;
  if (!WebPValidateConfig (&enc->webp_config)) {
    GST_ERROR_OBJECT (enc, "Failed to Validate the WebPConfig");
    return FALSE;
  }
  return TRUE;
}
Exemplo n.º 4
0
int main(int argc, const char *argv[]) {
  int return_value = -1;
  const char *in_file = NULL, *out_file = NULL, *dump_file = NULL;
  FILE *out = NULL;
  int c;
  int short_output = 0;
  int quiet = 0;
  int keep_alpha = 1;
  int blend_alpha = 0;
  uint32_t background_color = 0xffffffu;
  int crop = 0, crop_x = 0, crop_y = 0, crop_w = 0, crop_h = 0;
  int resize_w = 0, resize_h = 0;
  int lossless_preset = 6;
  int use_lossless_preset = -1;  // -1=unset, 0=don't use, 1=use it
  int show_progress = 0;
  int keep_metadata = 0;
  int metadata_written = 0;
  WebPPicture picture;
  int print_distortion = -1;        // -1=off, 0=PSNR, 1=SSIM, 2=LSIM
  WebPPicture original_picture;    // when PSNR or SSIM is requested
  WebPConfig config;
  WebPAuxStats stats;
  WebPMemoryWriter memory_writer;
  Metadata metadata;
  Stopwatch stop_watch;

  MetadataInit(&metadata);
  WebPMemoryWriterInit(&memory_writer);
  if (!WebPPictureInit(&picture) ||
      !WebPPictureInit(&original_picture) ||
      !WebPConfigInit(&config)) {
    fprintf(stderr, "Error! Version mismatch!\n");
    return -1;
  }

  if (argc == 1) {
    HelpShort();
    return 0;
  }

  for (c = 1; c < argc; ++c) {
    if (!strcmp(argv[c], "-h") || !strcmp(argv[c], "-help")) {
      HelpShort();
      return 0;
    } else if (!strcmp(argv[c], "-H") || !strcmp(argv[c], "-longhelp")) {
      HelpLong();
      return 0;
    } else if (!strcmp(argv[c], "-o") && c < argc - 1) {
      out_file = argv[++c];
    } else if (!strcmp(argv[c], "-d") && c < argc - 1) {
      dump_file = argv[++c];
      config.show_compressed = 1;
    } else if (!strcmp(argv[c], "-print_psnr")) {
      config.show_compressed = 1;
      print_distortion = 0;
    } else if (!strcmp(argv[c], "-print_ssim")) {
      config.show_compressed = 1;
      print_distortion = 1;
    } else if (!strcmp(argv[c], "-print_lsim")) {
      config.show_compressed = 1;
      print_distortion = 2;
    } else if (!strcmp(argv[c], "-short")) {
      ++short_output;
    } else if (!strcmp(argv[c], "-s") && c < argc - 2) {
      picture.width = strtol(argv[++c], NULL, 0);
      picture.height = strtol(argv[++c], NULL, 0);
    } else if (!strcmp(argv[c], "-m") && c < argc - 1) {
      config.method = strtol(argv[++c], NULL, 0);
      use_lossless_preset = 0;   // disable -z option
    } else if (!strcmp(argv[c], "-q") && c < argc - 1) {
      config.quality = (float)strtod(argv[++c], NULL);
      use_lossless_preset = 0;   // disable -z option
    } else if (!strcmp(argv[c], "-z") && c < argc - 1) {
      lossless_preset = strtol(argv[++c], NULL, 0);
      if (use_lossless_preset != 0) use_lossless_preset = 1;
    } else if (!strcmp(argv[c], "-alpha_q") && c < argc - 1) {
      config.alpha_quality = strtol(argv[++c], NULL, 0);
    } else if (!strcmp(argv[c], "-alpha_method") && c < argc - 1) {
      config.alpha_compression = strtol(argv[++c], NULL, 0);
    } else if (!strcmp(argv[c], "-alpha_cleanup")) {
      keep_alpha = keep_alpha ? 2 : 0;
    } else if (!strcmp(argv[c], "-blend_alpha") && c < argc - 1) {
      blend_alpha = 1;
      background_color = strtol(argv[++c], NULL, 16);  // <- parses '0x' prefix
      background_color = background_color & 0x00ffffffu;
    } else if (!strcmp(argv[c], "-alpha_filter") && c < argc - 1) {
      ++c;
      if (!strcmp(argv[c], "none")) {
        config.alpha_filtering = 0;
      } else if (!strcmp(argv[c], "fast")) {
        config.alpha_filtering = 1;
      } else if (!strcmp(argv[c], "best")) {
        config.alpha_filtering = 2;
      } else {
        fprintf(stderr, "Error! Unrecognized alpha filter: %s\n", argv[c]);
        goto Error;
      }
    } else if (!strcmp(argv[c], "-noalpha")) {
      keep_alpha = 0;
    } else if (!strcmp(argv[c], "-lossless")) {
      config.lossless = 1;
    } else if (!strcmp(argv[c], "-hint") && c < argc - 1) {
      ++c;
      if (!strcmp(argv[c], "photo")) {
        config.image_hint = WEBP_HINT_PHOTO;
      } else if (!strcmp(argv[c], "picture")) {
        config.image_hint = WEBP_HINT_PICTURE;
      } else if (!strcmp(argv[c], "graph")) {
        config.image_hint = WEBP_HINT_GRAPH;
      } else {
        fprintf(stderr, "Error! Unrecognized image hint: %s\n", argv[c]);
        goto Error;
      }
    } else if (!strcmp(argv[c], "-size") && c < argc - 1) {
      config.target_size = strtol(argv[++c], NULL, 0);
    } else if (!strcmp(argv[c], "-psnr") && c < argc - 1) {
      config.target_PSNR = (float)strtod(argv[++c], NULL);
    } else if (!strcmp(argv[c], "-sns") && c < argc - 1) {
      config.sns_strength = strtol(argv[++c], NULL, 0);
    } else if (!strcmp(argv[c], "-f") && c < argc - 1) {
      config.filter_strength = strtol(argv[++c], NULL, 0);
    } else if (!strcmp(argv[c], "-af")) {
      config.autofilter = 1;
    } else if (!strcmp(argv[c], "-jpeg_like")) {
      config.emulate_jpeg_size = 1;
    } else if (!strcmp(argv[c], "-mt")) {
      ++config.thread_level;  // increase thread level
    } else if (!strcmp(argv[c], "-low_memory")) {
      config.low_memory = 1;
    } else if (!strcmp(argv[c], "-strong")) {
      config.filter_type = 1;
    } else if (!strcmp(argv[c], "-nostrong")) {
      config.filter_type = 0;
    } else if (!strcmp(argv[c], "-sharpness") && c < argc - 1) {
      config.filter_sharpness = strtol(argv[++c], NULL, 0);
    } else if (!strcmp(argv[c], "-pass") && c < argc - 1) {
      config.pass = strtol(argv[++c], NULL, 0);
    } else if (!strcmp(argv[c], "-pre") && c < argc - 1) {
      config.preprocessing = strtol(argv[++c], NULL, 0);
    } else if (!strcmp(argv[c], "-segments") && c < argc - 1) {
      config.segments = strtol(argv[++c], NULL, 0);
    } else if (!strcmp(argv[c], "-partition_limit") && c < argc - 1) {
      config.partition_limit = strtol(argv[++c], NULL, 0);
    } else if (!strcmp(argv[c], "-map") && c < argc - 1) {
      picture.extra_info_type = strtol(argv[++c], NULL, 0);
#ifdef WEBP_EXPERIMENTAL_FEATURES
    } else if (!strcmp(argv[c], "-444")) {
      picture.colorspace = WEBP_YUV444;
    } else if (!strcmp(argv[c], "-422")) {
      picture.colorspace = WEBP_YUV422;
    } else if (!strcmp(argv[c], "-gray")) {
      picture.colorspace = WEBP_YUV400;
#endif
    } else if (!strcmp(argv[c], "-crop") && c < argc - 4) {
      crop = 1;
      crop_x = strtol(argv[++c], NULL, 0);
      crop_y = strtol(argv[++c], NULL, 0);
      crop_w = strtol(argv[++c], NULL, 0);
      crop_h = strtol(argv[++c], NULL, 0);
    } else if (!strcmp(argv[c], "-resize") && c < argc - 2) {
      resize_w = strtol(argv[++c], NULL, 0);
      resize_h = strtol(argv[++c], NULL, 0);
#ifndef WEBP_DLL
    } else if (!strcmp(argv[c], "-noasm")) {
      VP8GetCPUInfo = NULL;
#endif
    } else if (!strcmp(argv[c], "-version")) {
      const int version = WebPGetEncoderVersion();
      printf("%d.%d.%d\n",
        (version >> 16) & 0xff, (version >> 8) & 0xff, version & 0xff);
      return 0;
    } else if (!strcmp(argv[c], "-progress")) {
      show_progress = 1;
    } else if (!strcmp(argv[c], "-quiet")) {
      quiet = 1;
    } else if (!strcmp(argv[c], "-preset") && c < argc - 1) {
      WebPPreset preset;
      ++c;
      if (!strcmp(argv[c], "default")) {
        preset = WEBP_PRESET_DEFAULT;
      } else if (!strcmp(argv[c], "photo")) {
        preset = WEBP_PRESET_PHOTO;
      } else if (!strcmp(argv[c], "picture")) {
        preset = WEBP_PRESET_PICTURE;
      } else if (!strcmp(argv[c], "drawing")) {
        preset = WEBP_PRESET_DRAWING;
      } else if (!strcmp(argv[c], "icon")) {
        preset = WEBP_PRESET_ICON;
      } else if (!strcmp(argv[c], "text")) {
        preset = WEBP_PRESET_TEXT;
      } else {
        fprintf(stderr, "Error! Unrecognized preset: %s\n", argv[c]);
        goto Error;
      }
      if (!WebPConfigPreset(&config, preset, config.quality)) {
        fprintf(stderr, "Error! Could initialize configuration with preset.\n");
        goto Error;
      }
    } else if (!strcmp(argv[c], "-metadata") && c < argc - 1) {
      static const struct {
        const char* option;
        int flag;
      } kTokens[] = {
        { "all",  METADATA_ALL },
        { "none", 0 },
        { "exif", METADATA_EXIF },
        { "icc",  METADATA_ICC },
        { "xmp",  METADATA_XMP },
      };
      const size_t kNumTokens = sizeof(kTokens) / sizeof(kTokens[0]);
      const char* start = argv[++c];
      const char* const end = start + strlen(start);

      while (start < end) {
        size_t i;
        const char* token = strchr(start, ',');
        if (token == NULL) token = end;

        for (i = 0; i < kNumTokens; ++i) {
          if ((size_t)(token - start) == strlen(kTokens[i].option) &&
              !strncmp(start, kTokens[i].option, strlen(kTokens[i].option))) {
            if (kTokens[i].flag != 0) {
              keep_metadata |= kTokens[i].flag;
            } else {
              keep_metadata = 0;
            }
            break;
          }
        }
        if (i == kNumTokens) {
          fprintf(stderr, "Error! Unknown metadata type '%.*s'\n",
                  (int)(token - start), start);
          HelpLong();
          return -1;
        }
        start = token + 1;
      }
#ifdef HAVE_WINCODEC_H
      if (keep_metadata != 0 && keep_metadata != METADATA_ICC) {
        // TODO(jzern): remove when -metadata is supported on all platforms.
        fprintf(stderr, "Warning: only ICC profile extraction is currently"
                        " supported on this platform!\n");
      }
#endif
    } else if (!strcmp(argv[c], "-v")) {
      verbose = 1;
    } else if (!strcmp(argv[c], "--")) {
      if (c < argc - 1) in_file = argv[++c];
      break;
    } else if (argv[c][0] == '-') {
      fprintf(stderr, "Error! Unknown option '%s'\n", argv[c]);
      HelpLong();
      return -1;
    } else {
      in_file = argv[c];
    }
  }
Exemplo n.º 5
0
void save_as_webp(T1& file,
                  float quality,
                  int method,
                  int lossless,
                  int image_hint,
                  bool alpha,
                  T2 const& image)
{
    WebPConfig config;
    if (!WebPConfigPreset(&config, WEBP_PRESET_DEFAULT, quality))
    {
        throw std::runtime_error("version mismatch");
    }

    // Add additional tuning
    if (method >= 0) config.method = method;
#if (WEBP_ENCODER_ABI_VERSION >> 8) >= 1
    config.lossless = !!lossless;
    config.image_hint = static_cast<WebPImageHint>(image_hint);
#else
    #ifdef _MSC_VER
    #pragma NOTE(compiling against webp that does not support lossless flag)
    #else
    #warning "compiling against webp that does not support lossless flag"
    #endif
#endif

    bool valid = WebPValidateConfig(&config);
    if (!valid)
    {
        throw std::runtime_error("Invalid configuration");
    }

    WebPPicture pic;
    if (!WebPPictureInit(&pic))
    {
        throw std::runtime_error("version mismatch");
    }
    pic.width = image.width();
    pic.height = image.height();
    int ok = 0;
#if (WEBP_ENCODER_ABI_VERSION >> 8) >= 1
    pic.use_argb = !!lossless;
    // lossless fast track
    if (pic.use_argb)
    {
        pic.colorspace = static_cast<WebPEncCSP>(pic.colorspace | WEBP_CSP_ALPHA_BIT);
        if (WebPPictureAlloc(&pic)) {
            ok = 1;
            const int width = pic.width;
            const int height = pic.height;
            for (int y = 0; y < height; ++y) {
                typename T2::pixel_type const * row = image.getRow(y);
                for (int x = 0; x < width; ++x) {
                    const unsigned rgba = row[x];
                    unsigned a = (rgba >> 24) & 0xff;
                    unsigned r = rgba & 0xff;
                    unsigned g = (rgba >> 8 ) & 0xff;
                    unsigned b = (rgba >> 16) & 0xff;
                    const uint32_t argb = (a << 24) | (r << 16) | (g << 8) | (b);
                    pic.argb[x + y * pic.argb_stride] = argb;
                }
            }
        }
Exemplo n.º 6
0
int
encodeWEBP(Vbitmap *vbitmap, Ychannel *channelout, YmagineFormatOptions *options)
{
  int rc = YMAGINE_ERROR;

#if HAVE_WEBP
  WebPConfig config;
  WebPPicture picture;
  WebPPreset preset = WEBP_PRESET_PHOTO; // One of DEFAULT, PICTURE, PHOTO, DRAWING, ICON or TEXT
  int width;
  int height;
  int pitch;
  int quality;
  const unsigned char *pixels;
  int colormode;

  /*
   * List of encoding options for WebP config
   *   int lossless;           // Lossless encoding (0=lossy(default), 1=lossless).
   *   float quality;          // between 0 (smallest file) and 100 (biggest)
   *   int method;             // quality/speed trade-off (0=fast, 6=slower-better)
   *
   *   WebPImageHint image_hint;  // Hint for image type (lossless only for now).
   *
   *   // Parameters related to lossy compression only:
   *   int target_size;        // if non-zero, set the desired target size in bytes.
   *                           // Takes precedence over the 'compression' parameter.
   *   float target_PSNR;      // if non-zero, specifies the minimal distortion to
   *                           // try to achieve. Takes precedence over target_size.
   *   int segments;           // maximum number of segments to use, in [1..4]
   *   int sns_strength;       // Spatial Noise Shaping. 0=off, 100=maximum.
   *   int filter_strength;    // range: [0 = off .. 100 = strongest]
   *   int filter_sharpness;   // range: [0 = off .. 7 = least sharp]
   *   int filter_type;        // filtering type: 0 = simple, 1 = strong (only used
   *                           // if filter_strength > 0 or autofilter > 0)
   *   int autofilter;         // Auto adjust filter's strength [0 = off, 1 = on]
   *   int alpha_compression;  // Algorithm for encoding the alpha plane (0 = none,
   *                           // 1 = compressed with WebP lossless). Default is 1.
   *   int alpha_filtering;    // Predictive filtering method for alpha plane.
   *                           //  0: none, 1: fast, 2: best. Default if 1.
   *   int alpha_quality;      // Between 0 (smallest size) and 100 (lossless).
   *                           // Default is 100.
   *   int pass;               // number of entropy-analysis passes (in [1..10]).
   *
   *   int show_compressed;    // if true, export the compressed picture back.
   *                           // In-loop filtering is not applied.
   *   int preprocessing;      // preprocessing filter (0=none, 1=segment-smooth)
   *   int partitions;         // log2(number of token partitions) in [0..3]
   *                           // Default is set to 0 for easier progressive decoding.
   *   int partition_limit;    // quality degradation allowed to fit the 512k limit on
   *                           // prediction modes coding (0: no degradation,
   *                           // 100: maximum possible degradation).
   */

  colormode = VbitmapColormode(vbitmap);

  if (colormode != VBITMAP_COLOR_RGBA && colormode != VBITMAP_COLOR_RGB) {
    ALOGD("currently only support RGB, RGBA webp encoding");
    return rc;
  }

  quality = YmagineFormatOptions_normalizeQuality(options);

  if (!WebPConfigPreset(&config, preset, (float) quality)) {
    return YMAGINE_ERROR;   // version error
  }

  if (options && options->accuracy >= 0) {
    int method = options->accuracy / 15;
    if (method > 6) {
      method = 6;
    }
    config.method = method;
  }

  if (!WebPValidateConfig(&config)) {
    // parameter ranges verification failed
    return YMAGINE_ERROR;
  }

  rc = VbitmapLock(vbitmap);
  if (rc < 0) {
    ALOGE("AndroidBitmap_lockPixels() failed");
    return YMAGINE_ERROR;
  }

  width = VbitmapWidth(vbitmap);
  height = VbitmapHeight(vbitmap);
  pitch = VbitmapPitch(vbitmap);
  pixels = VbitmapBuffer(vbitmap);

  if (WebPPictureInit(&picture)) {
    picture.use_argb = 1;
    picture.width = width;
    picture.height = height;
    picture.writer = WebPYchannelWrite;
    picture.custom_ptr = channelout;

    if (colormode == VBITMAP_COLOR_RGBA) {
      WebPPictureImportRGBA(&picture, pixels, pitch);
    } else {
      WebPPictureImportRGB(&picture, pixels, pitch);
    }

    WebPEncode(&config, &picture);

    WebPPictureFree(&picture);
  }

  VbitmapUnlock(vbitmap);
  rc = YMAGINE_OK;
#endif

  return rc;
}
Exemplo n.º 7
0
/**
 * Convert bitmap object from Android code to WebP format. Save to file.
 */
jint Java_com_tbliss_android_seniorproject_webpconv_WebPConv_doConvJniGraphics2( JNIEnv* env,
																				 jobject javaThis,
																				 jobject jbitmap,
																				 jfloat jqualityFactor,
																				 jstring filename) 
{
	int ret = 0;
	float cqualityFactor;
	int stride, width, height;
	void* pixels; // pointer to address of bitmap
	int outputSize = 0;
	AndroidBitmapInfo bitmapInfo;
	uint8_t* outputPointer;
	uint8_t* cbitmapPointer;
	WebPConfig config;
	WebPMemoryWriter wrt;
	size_t dataWritten = 0;
	int bytesWritten = 0;
	FILE* fileout = NULL;
	const char* fname	= (*env)->GetStringUTFChars(env, filename, NULL);
	
	// Get Bitmap info (height/width/stride)
	if ((ret = AndroidBitmap_getInfo(env, jbitmap, &bitmapInfo)) < 0){
		LOGV("Could not get Bitmap info. error=%d", ret);
		return 0;
	}
	width = (int)bitmapInfo.width;
	height = (int)bitmapInfo.height;
	stride = (int)bitmapInfo.stride; // width * 4
	LOGV("Bitmap: width=%d, height=%d, stride=%d, format=%d", width, height, stride, bitmapInfo.format);
	
    // Lock Bitmap pixels
	if ((ret = AndroidBitmap_lockPixels(env, jbitmap, &pixels)) < 0) {
     LOGV("AndroidBitmap_lockPixels() failed ! error=%d", ret);
		 return 0;
    }

	cbitmapPointer = (uint8_t*)pixels;
	outputSize = stride * height;
	LOGV("output_size: %d", outputSize);
	outputPointer = (uint8_t*) malloc(outputSize);
	cqualityFactor = (float)jqualityFactor;
	
	// Setup a config
    if (!WebPConfigPreset(&config, WEBP_PRESET_PICTURE, cqualityFactor)) {
	    LOGV("WebPConfigPreset failed");
        return 0;   // version error
    }
    
    // ... additional tuning
	config.method = 1;
	LOGV("config.method = %d", config.method);
    
    if (WebPValidateConfig(&config) != 1) {
	    LOGV("Error with config");
	}

    // Setup the input data
    WebPPicture pic;
    if (!WebPPictureInit(&pic)) {
	    LOGV("WebPPictureInit failed");
        return 0;  // version error
    }

    pic.width = width;
    pic.height = height;
  	
    if (!WebPPictureImportRGBA(&pic, cbitmapPointer, stride)) {
		LOGV("WebPPictureImportRGB failed");
		return 0;
	}
	
    // Set up a byte-output write method. WebPMemoryWriter, for instance.
    pic.writer = MyMemoryWriter;
    pic.custom_ptr = &wrt;
    //InitMemoryWriter(&wrt);
	wrt.mem = &outputPointer;
	wrt.size = &dataWritten;
	wrt.max_size = outputSize;
	
    // Compress!
    ret = WebPEncode(&config, &pic);   // ok = 0 => error occurred!
	if (!ret) {
	    LOGV("ret == 0, WebPEncode fail");
	}
  
    WebPPictureFree(&pic);  // must be called independently of the 'ok' result.

	// Write to phone
	fileout = fopen(fname, "wb");
	if(!fileout){
		LOGV("cannot open output file %s", fname);
		return 0;
	}
	bytesWritten = fwrite(outputPointer, 1, dataWritten, fileout);
	LOGV("bytesWritten: %d", bytesWritten);
	
	// Unlock pixels of Bitmap
	fclose(fileout);
	AndroidBitmap_unlockPixels(env, jbitmap);
	free(outputPointer);
	(*env)->ReleaseStringUTFChars(env, filename, fname);
	
	return dataWritten;
}
Exemplo n.º 8
0
int main(int argc, const char *argv[]) {
  const char *in_file = NULL, *out_file = NULL, *dump_file = NULL;
  FILE *out = NULL;
  int c;
  int short_output = 0;
  int quiet = 0;
  int keep_alpha = 0;
  int crop = 0, crop_x = 0, crop_y = 0, crop_w = 0, crop_h = 0;
  int resize_w = 0, resize_h = 0;
  WebPPicture picture;
  WebPConfig config;
  WebPAuxStats stats;
  Stopwatch stop_watch;

#ifdef WEBP_EXPERIMENTAL_FEATURES
  keep_alpha = 1;
#endif

  if (!WebPPictureInit(&picture) || !WebPConfigInit(&config)) {
    fprintf(stderr, "Error! Version mismatch!\n");
    goto Error;
  }

  if (argc == 1) {
    HelpShort();
    return 0;
  }

  for (c = 1; c < argc; ++c) {
    if (!strcmp(argv[c], "-h") || !strcmp(argv[c], "-help")) {
      HelpShort();
      return 0;
    } else if (!strcmp(argv[c], "-H") || !strcmp(argv[c], "-longhelp")) {
      HelpLong();
      return 0;
    } else if (!strcmp(argv[c], "-o") && c < argc - 1) {
      out_file = argv[++c];
    } else if (!strcmp(argv[c], "-d") && c < argc - 1) {
      dump_file = argv[++c];
      config.show_compressed = 1;
    } else if (!strcmp(argv[c], "-short")) {
      short_output++;
    } else if (!strcmp(argv[c], "-s") && c < argc - 2) {
      picture.width = strtol(argv[++c], NULL, 0);
      picture.height = strtol(argv[++c], NULL, 0);
    } else if (!strcmp(argv[c], "-m") && c < argc - 1) {
      config.method = strtol(argv[++c], NULL, 0);
    } else if (!strcmp(argv[c], "-q") && c < argc - 1) {
      config.quality = (float)strtod(argv[++c], NULL);
    } else if (!strcmp(argv[c], "-size") && c < argc - 1) {
      config.target_size = strtol(argv[++c], NULL, 0);
    } else if (!strcmp(argv[c], "-psnr") && c < argc - 1) {
      config.target_PSNR = (float)strtod(argv[++c], NULL);
    } else if (!strcmp(argv[c], "-sns") && c < argc - 1) {
      config.sns_strength = strtol(argv[++c], NULL, 0);
    } else if (!strcmp(argv[c], "-f") && c < argc - 1) {
      config.filter_strength = strtol(argv[++c], NULL, 0);
    } else if (!strcmp(argv[c], "-af")) {
      config.autofilter = 1;
    } else if (!strcmp(argv[c], "-strong")) {
      config.filter_type = 1;
    } else if (!strcmp(argv[c], "-sharpness") && c < argc - 1) {
      config.filter_sharpness = strtol(argv[++c], NULL, 0);
    } else if (!strcmp(argv[c], "-pass") && c < argc - 1) {
      config.pass = strtol(argv[++c], NULL, 0);
    } else if (!strcmp(argv[c], "-pre") && c < argc - 1) {
      config.preprocessing = strtol(argv[++c], NULL, 0);
    } else if (!strcmp(argv[c], "-segments") && c < argc - 1) {
      config.segments = strtol(argv[++c], NULL, 0);
    } else if (!strcmp(argv[c], "-partition_limit") && c < argc - 1) {
      config.partition_limit = strtol(argv[++c], NULL, 0);
#ifdef WEBP_EXPERIMENTAL_FEATURES
    } else if (!strcmp(argv[c], "-alpha_comp") && c < argc - 1) {
      config.alpha_compression = strtol(argv[++c], NULL, 0);
    } else if (!strcmp(argv[c], "-noalpha")) {
      keep_alpha = 0;
#endif
    } else if (!strcmp(argv[c], "-map") && c < argc - 1) {
      picture.extra_info_type = strtol(argv[++c], NULL, 0);
#ifdef WEBP_EXPERIMENTAL_FEATURES
    } else if (!strcmp(argv[c], "-444")) {
      picture.colorspace = WEBP_YUV444;
    } else if (!strcmp(argv[c], "-422")) {
      picture.colorspace = WEBP_YUV422;
    } else if (!strcmp(argv[c], "-gray")) {
      picture.colorspace = WEBP_YUV400;
#endif
    } else if (!strcmp(argv[c], "-crop") && c < argc - 4) {
      crop = 1;
      crop_x = strtol(argv[++c], NULL, 0);
      crop_y = strtol(argv[++c], NULL, 0);
      crop_w = strtol(argv[++c], NULL, 0);
      crop_h = strtol(argv[++c], NULL, 0);
    } else if (!strcmp(argv[c], "-resize") && c < argc - 2) {
      resize_w = strtol(argv[++c], NULL, 0);
      resize_h = strtol(argv[++c], NULL, 0);
#ifndef WEBP_DLL
    } else if (!strcmp(argv[c], "-noasm")) {
      VP8GetCPUInfo = NULL;
#endif
    } else if (!strcmp(argv[c], "-version")) {
      const int version = WebPGetEncoderVersion();
      printf("%d.%d.%d\n",
        (version >> 16) & 0xff, (version >> 8) & 0xff, version & 0xff);
      return 0;
    } else if (!strcmp(argv[c], "-quiet")) {
      quiet = 1;
    } else if (!strcmp(argv[c], "-preset") && c < argc - 1) {
      WebPPreset preset;
      ++c;
      if (!strcmp(argv[c], "default")) {
        preset = WEBP_PRESET_DEFAULT;
      } else if (!strcmp(argv[c], "photo")) {
        preset = WEBP_PRESET_PHOTO;
      } else if (!strcmp(argv[c], "picture")) {
        preset = WEBP_PRESET_PICTURE;
      } else if (!strcmp(argv[c], "drawing")) {
        preset = WEBP_PRESET_DRAWING;
      } else if (!strcmp(argv[c], "icon")) {
        preset = WEBP_PRESET_ICON;
      } else if (!strcmp(argv[c], "text")) {
        preset = WEBP_PRESET_TEXT;
      } else {
        fprintf(stderr, "Error! Unrecognized preset: %s\n", argv[c]);
        goto Error;
      }
      if (!WebPConfigPreset(&config, preset, config.quality)) {
        fprintf(stderr, "Error! Could initialize configuration with preset.\n");
        goto Error;
      }
    } else if (!strcmp(argv[c], "-v")) {
      verbose = 1;
    } else if (argv[c][0] == '-') {
      fprintf(stderr, "Error! Unknown option '%s'\n", argv[c]);
      HelpLong();
      return -1;
    } else {
      in_file = argv[c];
    }
  }
Exemplo n.º 9
0
static gboolean
real_save_webp (GdkPixbuf        *pixbuf,
                gchar           **keys,
                gchar           **values,
                GError          **error,
                gboolean          to_callback,
                FILE             *f,
                save_context     *context)
{
        WebPPicture picture;
        WebPConfig config;
        gint w, h, rowstride, has_alpha, rc;
        guchar *pixels;

        if (!WebPPictureInit(&picture) || !WebPConfigInit(&config)) {
                g_set_error(error,
                            GDK_PIXBUF_ERROR,
                            GDK_PIXBUF_ERROR_BAD_OPTION,
                            "WebP encoder version mismatch.");
                return FALSE;
        }

        if (keys && *keys) {
                gchar **kiter = keys;
                gchar **viter = values;

                while (*kiter) {
                        if (strncmp (*kiter, "quality", 7) == 0) {
                                float quality = (float) g_ascii_strtod (*viter, NULL);
                                if (quality < 0 || quality > 100) {
                                        g_set_error (error,
                                                     GDK_PIXBUF_ERROR,
                                                     GDK_PIXBUF_ERROR_BAD_OPTION,
                                                     "WebP quality must be a value between 0 and 100.");
                                        return FALSE;
                                }
                                config.quality = quality;
                        } else if (strncmp (*kiter, "preset", 6) == 0) {
                                WebPPreset preset;
                                if (strncmp (*viter, "default", 7) == 0) {
                                        preset = WEBP_PRESET_DEFAULT;
                                } else if (strncmp (*viter, "photo", 5) == 0) {
                                        preset = WEBP_PRESET_PHOTO;
                                } else if (strncmp (*viter, "picture", 7) == 0) {
                                        preset = WEBP_PRESET_PICTURE;
                                } else if (strncmp (*viter, "drawing", 7) == 0) {
                                        preset = WEBP_PRESET_DRAWING;
                                } else if (strncmp (*viter, "icon", 4) == 0) {
                                        preset = WEBP_PRESET_ICON;
                                } else if (strncmp (*viter, "text", 4) == 0) {
                                        preset = WEBP_PRESET_TEXT;
                                } else {
                                        g_set_error (error,
                                                     GDK_PIXBUF_ERROR,
                                                     GDK_PIXBUF_ERROR_BAD_OPTION,
                                                     "WebP encoder invalid preset.");
                                        return FALSE;
                                }
                                if (WebPConfigPreset (&config, preset, config.quality) == 0) {
                                         g_set_error (error,
                                                      GDK_PIXBUF_ERROR,
                                                      GDK_PIXBUF_ERROR_FAILED,
                                                      "Could not initialize decoder with preset.");
                                         return FALSE;
                                }
                        }
                        ++kiter;
                        ++viter;
                }
        }

        if (WebPValidateConfig (&config) != 1) {
                g_set_error (error,
                             GDK_PIXBUF_ERROR,
                             GDK_PIXBUF_ERROR_BAD_OPTION,
                             "Invalid encoding configuration");
                return FALSE;
        }

        w = gdk_pixbuf_get_width (pixbuf);
        h = gdk_pixbuf_get_height (pixbuf);
        rowstride = gdk_pixbuf_get_rowstride (pixbuf);
        has_alpha = gdk_pixbuf_get_has_alpha (pixbuf);
        pixels = gdk_pixbuf_get_pixels (pixbuf);

        picture.width = w;
        picture.height = h;

        if (has_alpha) {
                rc = WebPPictureImportRGBA (&picture, pixels, rowstride);
        } else {
                rc = WebPPictureImportRGB (&picture, pixels, rowstride);
        }
        if (rc == 0) {
                g_set_error (error,
                             GDK_PIXBUF_ERROR,
                             GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY,
                             "Failed to allocate picture");
                return FALSE;
        }

        if (to_callback) {
                picture.writer = save_callback;
                picture.custom_ptr = (void*) context;
        } else {
                picture.writer = write_file;
                picture.custom_ptr = (void*) f;
        }

        if (WebPEncode(&config, &picture) == 0) {
                fprintf(stderr, "Error! Cannot encode picture as WebP\n");
        }

        return TRUE;
}
Exemplo n.º 10
0
status_t
WebPTranslator::_TranslateFromBits(BPositionIO* stream, BMessage* ioExtension,
		uint32 outType, BPositionIO* target)
{
	if (!outType)
		outType = WEBP_IMAGE_FORMAT;
	if (outType != WEBP_IMAGE_FORMAT)
		return B_NO_TRANSLATOR;

	TranslatorBitmap bitsHeader;
	status_t status;

	status = identify_bits_header(stream, NULL, &bitsHeader);
	if (status != B_OK)
		return status;

	if (bitsHeader.colors == B_CMAP8) {
		// TODO: support whatever colospace by intermediate colorspace conversion
		printf("Error! Colorspace not supported\n");
		return B_NO_TRANSLATOR;
	}

	int32 bitsBytesPerPixel = 0;
	switch (bitsHeader.colors) {
		case B_RGB32:
		case B_RGB32_BIG:
		case B_RGBA32:
		case B_RGBA32_BIG:
		case B_CMY32:
		case B_CMYA32:
		case B_CMYK32:
			bitsBytesPerPixel = 4;
			break;

		case B_RGB24:
		case B_RGB24_BIG:
		case B_CMY24:
			bitsBytesPerPixel = 3;
			break;

		case B_RGB16:
		case B_RGB16_BIG:
		case B_RGBA15:
		case B_RGBA15_BIG:
		case B_RGB15:
		case B_RGB15_BIG:
			bitsBytesPerPixel = 2;
			break;

		case B_CMAP8:
		case B_GRAY8:
			bitsBytesPerPixel = 1;
			break;

		default:
			return B_ERROR;
	}

	if (bitsBytesPerPixel < 3) {
		// TODO support
		return B_NO_TRANSLATOR;
	}

	WebPPicture picture;
	WebPConfig config;

	if (!WebPPictureInit(&picture) || !WebPConfigInit(&config)) {
		printf("Error! Version mismatch!\n");
  		return B_ERROR;
	}

	WebPPreset preset = (WebPPreset)fSettings->SetGetInt32(WEBP_SETTING_PRESET);
	config.quality = (float)fSettings->SetGetInt32(WEBP_SETTING_QUALITY);

	if (!WebPConfigPreset(&config, (WebPPreset)preset, config.quality)) {
		printf("Error! Could initialize configuration with preset.");
		return B_ERROR;
	}

	config.method = fSettings->SetGetInt32(WEBP_SETTING_METHOD);
	config.preprocessing = fSettings->SetGetBool(WEBP_SETTING_PREPROCESSING);

	if (!WebPValidateConfig(&config)) {
		printf("Error! Invalid configuration.\n");
 		return B_ERROR;
	}

	picture.width = bitsHeader.bounds.IntegerWidth() + 1;
	picture.height = bitsHeader.bounds.IntegerHeight() + 1;

	int stride = bitsHeader.rowBytes;
	int bitsSize = picture.height * stride;
	uint8* bits = (uint8*)malloc(bitsSize);
	if (bits == NULL)
		return B_NO_MEMORY;

	if (stream->Read(bits, bitsSize) != bitsSize) {
		free(bits);
		return B_IO_ERROR;
	}

	if (!WebPPictureImportBGRA(&picture, bits, stride)) {
		printf("Error! WebPEncode() failed!\n");
		free(bits);
		return B_ERROR;
	}
	free(bits);

	picture.writer = _EncodedWriter;
	picture.custom_ptr = target;
	picture.stats = NULL;

	if (!WebPEncode(&config, &picture)) {
		printf("Error! WebPEncode() failed!\n");
		status = B_NO_TRANSLATOR;
	} else
		status = B_OK;

	WebPPictureFree(&picture);
	return status;
}
Exemplo n.º 11
0
/* Save a layer from an image */
gboolean save_layer(gint32             drawable_ID,
                    WebPWriterFunction writer,
                    void              *custom_ptr,
#ifdef WEBP_0_5
                    gboolean           animation,
                    WebPAnimEncoder   *enc,
                    int                frame_timestamp,
#endif
                    WebPSaveParams    *params,
                    GError           **error)
{
    gboolean          status   = FALSE;
    gint              bpp;
    gint              width;
    gint              height;
    GimpImageType     drawable_type;
    WebPConfig        config;
    WebPPicture       picture;
    guchar           *buffer   = NULL;
#ifdef GIMP_2_9
    GeglBuffer       *geglbuffer;
    GeglRectangle     extent;
#else
    GimpDrawable     *drawable = NULL;
    GimpPixelRgn      region;
#endif

    /* Retrieve the image data */
    bpp = gimp_drawable_bpp(drawable_ID);
    width = gimp_drawable_width(drawable_ID);
    height = gimp_drawable_height(drawable_ID);
    drawable_type = gimp_drawable_type(drawable_ID);

    /* Initialize the WebP configuration with a preset and fill in the
     * remaining values */
    WebPConfigPreset(&config,
                     webp_preset_by_name(params->preset),
                     params->quality);

    config.lossless      = params->lossless;
    config.method        = 6;  /* better quality */
    config.alpha_quality = params->alpha_quality;

    /* Prepare the WebP structure */
    WebPPictureInit(&picture);
    picture.use_argb      = 1;
    picture.width         = width;
    picture.height        = height;
    picture.writer        = writer;
    picture.custom_ptr    = custom_ptr;
    picture.progress_hook = webp_file_progress;

    do {
        /* Attempt to allocate a buffer of the appropriate size */
        buffer = (guchar *)g_malloc(bpp * width * height);
        if(!buffer) {
            g_set_error(error,
                        G_FILE_ERROR,
                        0,
                        "Unable to allocate buffer for layer");
            break;
        }

#ifdef GIMP_2_9
        /* Obtain the buffer and get its extent */
        geglbuffer = gimp_drawable_get_buffer(drawable_ID);
        extent = *gegl_buffer_get_extent(geglbuffer);

        /* Read the layer buffer into our buffer */
        gegl_buffer_get(geglbuffer, &extent, 1.0, NULL, buffer,
                        GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);

        g_object_unref(geglbuffer);
#else
        /* Get the drawable */
        drawable = gimp_drawable_get(drawable_ID);

        /* Obtain the pixel region for the drawable */
        gimp_pixel_rgn_init(&region,
                            drawable,
                            0, 0,
                            width,
                            height,
                            FALSE, FALSE);

        /* Read the region into the buffer */
        gimp_pixel_rgn_get_rect(&region,
                                buffer,
                                0, 0,
                                width,
                                height);

        gimp_drawable_detach(drawable);
#endif

        /* Use the appropriate function to import the data from the buffer */
        if(drawable_type == GIMP_RGB_IMAGE) {
            WebPPictureImportRGB(&picture, buffer, width * bpp);
        } else {
            WebPPictureImportRGBA(&picture, buffer, width * bpp);
        }

#ifdef WEBP_0_5
        if (animation == TRUE) {

            if (!WebPAnimEncoderAdd(enc, &picture, frame_timestamp, &config)) {
                g_set_error(error,
                            G_FILE_ERROR,
                            picture.error_code,
                            "WebP error: '%s'",
                            webp_error_string(picture.error_code));
                break;
            }
        } else {
#endif
            if(!WebPEncode(&config, &picture)) {
                g_set_error(error,
                            G_FILE_ERROR,
                            picture.error_code,
                            "WebP error: '%s'",
                            webp_error_string(picture.error_code));
                break;
            }
#ifdef WEBP_0_5
        }
#endif

        /* Everything succeeded */
        status = TRUE;

    } while(0);

    /* Free the buffer */
    if (buffer) {
        free(buffer);
    }

    return status;
}