Blame extras/extras.c

Packit 9c6abc
// Copyright 2015 Google Inc. All Rights Reserved.
Packit 9c6abc
//
Packit 9c6abc
// Use of this source code is governed by a BSD-style license
Packit 9c6abc
// that can be found in the COPYING file in the root of the source
Packit 9c6abc
// tree. An additional intellectual property rights grant can be found
Packit 9c6abc
// in the file PATENTS. All contributing project authors may
Packit 9c6abc
// be found in the AUTHORS file in the root of the source tree.
Packit 9c6abc
// -----------------------------------------------------------------------------
Packit 9c6abc
//
Packit 9c6abc
//  Additional WebP utilities.
Packit 9c6abc
//
Packit 9c6abc
Packit 9c6abc
#include "extras/extras.h"
Packit 9c6abc
#include "webp/format_constants.h"
Packit 9c6abc
Packit 9c6abc
#include <assert.h>
Packit 9c6abc
#include <string.h>
Packit 9c6abc
Packit 9c6abc
#define XTRA_MAJ_VERSION 1
Packit 9c6abc
#define XTRA_MIN_VERSION 0
Packit 9c6abc
#define XTRA_REV_VERSION 0
Packit 9c6abc
Packit 9c6abc
//------------------------------------------------------------------------------
Packit 9c6abc
Packit 9c6abc
int WebPGetExtrasVersion(void) {
Packit 9c6abc
  return (XTRA_MAJ_VERSION << 16) | (XTRA_MIN_VERSION << 8) | XTRA_REV_VERSION;
Packit 9c6abc
}
Packit 9c6abc
Packit 9c6abc
//------------------------------------------------------------------------------
Packit 9c6abc
Packit 9c6abc
int WebPImportGray(const uint8_t* gray_data, WebPPicture* pic) {
Packit 9c6abc
  int y, width, uv_width;
Packit 9c6abc
  if (pic == NULL || gray_data == NULL) return 0;
Packit 9c6abc
  pic->colorspace = WEBP_YUV420;
Packit 9c6abc
  if (!WebPPictureAlloc(pic)) return 0;
Packit 9c6abc
  width = pic->width;
Packit 9c6abc
  uv_width = (width + 1) >> 1;
Packit 9c6abc
  for (y = 0; y < pic->height; ++y) {
Packit 9c6abc
    memcpy(pic->y + y * pic->y_stride, gray_data, width);
Packit 9c6abc
    gray_data += width;    // <- we could use some 'data_stride' here if needed
Packit 9c6abc
    if ((y & 1) == 0) {
Packit 9c6abc
      memset(pic->u + (y >> 1) * pic->uv_stride, 128, uv_width);
Packit 9c6abc
      memset(pic->v + (y >> 1) * pic->uv_stride, 128, uv_width);
Packit 9c6abc
    }
Packit 9c6abc
  }
Packit 9c6abc
  return 1;
Packit 9c6abc
}
Packit 9c6abc
Packit 9c6abc
int WebPImportRGB565(const uint8_t* rgb565, WebPPicture* pic) {
Packit 9c6abc
  int x, y;
Packit 9c6abc
  uint32_t* dst;
Packit 9c6abc
  if (pic == NULL || rgb565 == NULL) return 0;
Packit 9c6abc
  pic->colorspace = WEBP_YUV420;
Packit 9c6abc
  pic->use_argb = 1;
Packit 9c6abc
  if (!WebPPictureAlloc(pic)) return 0;
Packit 9c6abc
  dst = pic->argb;
Packit 9c6abc
  for (y = 0; y < pic->height; ++y) {
Packit 9c6abc
    const int width = pic->width;
Packit 9c6abc
    for (x = 0; x < width; ++x) {
Packit 9c6abc
#ifdef WEBP_SWAP_16BIT_CSP
Packit 9c6abc
      const uint32_t rg = rgb565[2 * x + 1];
Packit 9c6abc
      const uint32_t gb = rgb565[2 * x + 0];
Packit 9c6abc
#else
Packit 9c6abc
      const uint32_t rg = rgb565[2 * x + 0];
Packit 9c6abc
      const uint32_t gb = rgb565[2 * x + 1];
Packit 9c6abc
#endif
Packit 9c6abc
      uint32_t r = rg & 0xf8;
Packit 9c6abc
      uint32_t g = ((rg << 5) | (gb >> 3)) & 0xfc;
Packit 9c6abc
      uint32_t b = (gb << 5);
Packit 9c6abc
      // dithering
Packit 9c6abc
      r = r | (r >> 5);
Packit 9c6abc
      g = g | (g >> 6);
Packit 9c6abc
      b = b | (b >> 5);
Packit 9c6abc
      dst[x] = (0xffu << 24) | (r << 16) | (g << 8) | b;
Packit 9c6abc
    }
Packit 9c6abc
    rgb565 += 2 * width;
Packit 9c6abc
    dst += pic->argb_stride;
Packit 9c6abc
  }
Packit 9c6abc
  return 1;
Packit 9c6abc
}
Packit 9c6abc
Packit 9c6abc
int WebPImportRGB4444(const uint8_t* rgb4444, WebPPicture* pic) {
Packit 9c6abc
  int x, y;
Packit 9c6abc
  uint32_t* dst;
Packit 9c6abc
  if (pic == NULL || rgb4444 == NULL) return 0;
Packit 9c6abc
  pic->colorspace = WEBP_YUV420;
Packit 9c6abc
  pic->use_argb = 1;
Packit 9c6abc
  if (!WebPPictureAlloc(pic)) return 0;
Packit 9c6abc
  dst = pic->argb;
Packit 9c6abc
  for (y = 0; y < pic->height; ++y) {
Packit 9c6abc
    const int width = pic->width;
Packit 9c6abc
    for (x = 0; x < width; ++x) {
Packit 9c6abc
#ifdef WEBP_SWAP_16BIT_CSP
Packit 9c6abc
      const uint32_t rg = rgb4444[2 * x + 1];
Packit 9c6abc
      const uint32_t ba = rgb4444[2 * x + 0];
Packit 9c6abc
#else
Packit 9c6abc
      const uint32_t rg = rgb4444[2 * x + 0];
Packit 9c6abc
      const uint32_t ba = rgb4444[2 * x + 1];
Packit 9c6abc
#endif
Packit 9c6abc
      uint32_t r = rg & 0xf0;
Packit 9c6abc
      uint32_t g = (rg << 4);
Packit 9c6abc
      uint32_t b = (ba & 0xf0);
Packit 9c6abc
      uint32_t a = (ba << 4);
Packit 9c6abc
      // dithering
Packit 9c6abc
      r = r | (r >> 4);
Packit 9c6abc
      g = g | (g >> 4);
Packit 9c6abc
      b = b | (b >> 4);
Packit 9c6abc
      a = a | (a >> 4);
Packit 9c6abc
      dst[x] = (a << 24) | (r << 16) | (g << 8) | b;
Packit 9c6abc
    }
Packit 9c6abc
    rgb4444 += 2 * width;
Packit 9c6abc
    dst += pic->argb_stride;
Packit 9c6abc
  }
Packit 9c6abc
  return 1;
Packit 9c6abc
}
Packit 9c6abc
Packit 9c6abc
int WebPImportColorMappedARGB(const uint8_t* indexed, int indexed_stride,
Packit 9c6abc
                              const uint32_t palette[], int palette_size,
Packit 9c6abc
                              WebPPicture* pic) {
Packit 9c6abc
  int x, y;
Packit 9c6abc
  uint32_t* dst;
Packit 9c6abc
  // 256 as the input buffer is uint8_t.
Packit 9c6abc
  assert(MAX_PALETTE_SIZE <= 256);
Packit 9c6abc
  if (pic == NULL || indexed == NULL || indexed_stride < pic->width ||
Packit 9c6abc
      palette == NULL || palette_size > MAX_PALETTE_SIZE || palette_size <= 0) {
Packit 9c6abc
    return 0;
Packit 9c6abc
  }
Packit 9c6abc
  pic->use_argb = 1;
Packit 9c6abc
  if (!WebPPictureAlloc(pic)) return 0;
Packit 9c6abc
  dst = pic->argb;
Packit 9c6abc
  for (y = 0; y < pic->height; ++y) {
Packit 9c6abc
    for (x = 0; x < pic->width; ++x) {
Packit 9c6abc
      // Make sure we are within the palette.
Packit 9c6abc
      if (indexed[x] >= palette_size) {
Packit 9c6abc
        WebPPictureFree(pic);
Packit 9c6abc
        return 0;
Packit 9c6abc
      }
Packit 9c6abc
      dst[x] = palette[indexed[x]];
Packit 9c6abc
    }
Packit 9c6abc
    indexed += indexed_stride;
Packit 9c6abc
    dst += pic->argb_stride;
Packit 9c6abc
  }
Packit 9c6abc
  return 1;
Packit 9c6abc
}
Packit 9c6abc
Packit 9c6abc
//------------------------------------------------------------------------------