1474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org/*
2474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
3474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org *
4474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org *  Use of this source code is governed by a BSD-style license
5474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org *  that can be found in the LICENSE file in the root of the source
6474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org *  tree. An additional intellectual property rights grant can be found
7474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org *  in the file PATENTS.  All contributing project authors may
8474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org *  be found in the AUTHORS file in the root of the source tree.
9474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org */
10474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
11474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#include <stdlib.h>
12474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#include <string.h>
13ace65784417788374f0b19ce5a8abd06c9ccd007johannkoenig@chromium.org
14474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org#include "vpx/vpx_image.h"
15ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org#include "vpx/vpx_integer.h"
16ace65784417788374f0b19ce5a8abd06c9ccd007johannkoenig@chromium.org#include "vpx_mem/vpx_mem.h"
17167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org
18e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.orgstatic vpx_image_t *img_alloc_helper(vpx_image_t   *img,
19e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org                                     vpx_img_fmt_t  fmt,
20e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org                                     unsigned int   d_w,
21e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org                                     unsigned int   d_h,
22e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org                                     unsigned int   buf_align,
23e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org                                     unsigned int   stride_align,
24e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org                                     unsigned char *img_data) {
25474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
266fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  unsigned int  h, w, s, xcs, ycs, bps;
276fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  int           align;
28474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
296fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  /* Treat align==0 like align==1 */
306fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  if (!buf_align)
316fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    buf_align = 1;
32167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org
336fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  /* Validate alignment (must be power of 2) */
346fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  if (buf_align & (buf_align - 1))
356fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    goto fail;
36167514562bbce1eb0566271d6cb41d90d2b5ffa0hclam@chromium.org
376fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  /* Treat align==0 like align==1 */
386fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  if (!stride_align)
396fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    stride_align = 1;
40474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
416fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  /* Validate alignment (must be power of 2) */
426fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  if (stride_align & (stride_align - 1))
436fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    goto fail;
44474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
456fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  /* Get sample size for this format */
466fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  switch (fmt) {
47474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    case VPX_IMG_FMT_RGB32:
48474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    case VPX_IMG_FMT_RGB32_LE:
49474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    case VPX_IMG_FMT_ARGB:
50474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    case VPX_IMG_FMT_ARGB_LE:
516fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      bps = 32;
526fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      break;
53474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    case VPX_IMG_FMT_RGB24:
54474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    case VPX_IMG_FMT_BGR24:
556fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      bps = 24;
566fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      break;
57474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    case VPX_IMG_FMT_RGB565:
58474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    case VPX_IMG_FMT_RGB565_LE:
59474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    case VPX_IMG_FMT_RGB555:
60474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    case VPX_IMG_FMT_RGB555_LE:
61474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    case VPX_IMG_FMT_UYVY:
62474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    case VPX_IMG_FMT_YUY2:
63474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    case VPX_IMG_FMT_YVYU:
646fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      bps = 16;
656fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      break;
66474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    case VPX_IMG_FMT_I420:
67474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    case VPX_IMG_FMT_YV12:
68474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    case VPX_IMG_FMT_VPXI420:
69474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    case VPX_IMG_FMT_VPXYV12:
706fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      bps = 12;
716fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      break;
72e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org    case VPX_IMG_FMT_I422:
73e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org      bps = 16;
74e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org      break;
75e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org    case VPX_IMG_FMT_I444:
76e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org      bps = 24;
77e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org      break;
78e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org    case VPX_IMG_FMT_I42016:
79e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org      bps = 24;
80e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org      break;
81e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org    case VPX_IMG_FMT_I42216:
82e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org      bps = 32;
83e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org      break;
84e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org    case VPX_IMG_FMT_I44416:
85e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org      bps = 48;
86e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org      break;
87474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    default:
886fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      bps = 16;
896fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      break;
906fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  }
91474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
926fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  /* Get chroma shift values for this format */
936fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  switch (fmt) {
94474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    case VPX_IMG_FMT_I420:
95474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    case VPX_IMG_FMT_YV12:
96474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    case VPX_IMG_FMT_VPXI420:
97474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    case VPX_IMG_FMT_VPXYV12:
98e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org    case VPX_IMG_FMT_I422:
99e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org    case VPX_IMG_FMT_I42016:
100e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org    case VPX_IMG_FMT_I42216:
1016fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      xcs = 1;
1026fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      break;
103474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    default:
1046fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      xcs = 0;
1056fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      break;
1066fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  }
107474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1086fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  switch (fmt) {
109474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    case VPX_IMG_FMT_I420:
110474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    case VPX_IMG_FMT_YV12:
111474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    case VPX_IMG_FMT_VPXI420:
112474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    case VPX_IMG_FMT_VPXYV12:
1136fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      ycs = 1;
1146fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      break;
115474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    default:
1166fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      ycs = 0;
1176fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      break;
1186fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  }
1196fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
1206fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  /* Calculate storage sizes given the chroma subsampling */
1216fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  align = (1 << xcs) - 1;
1226fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  w = (d_w + align) & ~align;
1236fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  align = (1 << ycs) - 1;
1246fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  h = (d_h + align) & ~align;
1256fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  s = (fmt & VPX_IMG_FMT_PLANAR) ? w : bps * w / 8;
1266fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  s = (s + stride_align - 1) & ~(stride_align - 1);
1276fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
1286fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  /* Allocate the new image */
1296fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  if (!img) {
1306fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    img = (vpx_image_t *)calloc(1, sizeof(vpx_image_t));
131474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
132474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    if (!img)
1336fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      goto fail;
134474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1356fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    img->self_allocd = 1;
1366fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  } else {
1376fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    memset(img, 0, sizeof(vpx_image_t));
1386fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  }
139474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1406fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  img->img_data = img_data;
141474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1426fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  if (!img_data) {
143ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org    const uint64_t alloc_size = (fmt & VPX_IMG_FMT_PLANAR) ?
144ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org                                (uint64_t)h * s * bps / 8 : (uint64_t)h * s;
145ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org
146ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org    if (alloc_size != (size_t)alloc_size)
147ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org      goto fail;
148ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org
149ace65784417788374f0b19ce5a8abd06c9ccd007johannkoenig@chromium.org    img->img_data = (uint8_t *)vpx_memalign(buf_align, (size_t)alloc_size);
1506fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    img->img_data_owner = 1;
1516fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  }
152474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1536fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  if (!img->img_data)
1546fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    goto fail;
155474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1566fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  img->fmt = fmt;
157d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org  img->bit_depth = (fmt & VPX_IMG_FMT_HIGHBITDEPTH) ? 16 : 8;
1586fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  img->w = w;
1596fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  img->h = h;
1606fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  img->x_chroma_shift = xcs;
1616fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  img->y_chroma_shift = ycs;
1626fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  img->bps = bps;
163474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1646fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  /* Calculate strides */
1656fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  img->stride[VPX_PLANE_Y] = img->stride[VPX_PLANE_ALPHA] = s;
1666fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  img->stride[VPX_PLANE_U] = img->stride[VPX_PLANE_V] = s >> xcs;
167474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
1686fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  /* Default viewport to entire image */
1696fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  if (!vpx_img_set_rect(img, 0, 0, d_w, d_h))
1706fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    return img;
171474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
172474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgfail:
1736fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  vpx_img_free(img);
1746fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  return NULL;
175474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org}
176474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
177474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgvpx_image_t *vpx_img_alloc(vpx_image_t  *img,
178474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                           vpx_img_fmt_t fmt,
179474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                           unsigned int  d_w,
180474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                           unsigned int  d_h,
1816fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org                           unsigned int  align) {
1826fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  return img_alloc_helper(img, fmt, d_w, d_h, align, align, NULL);
183474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org}
184474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
185474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgvpx_image_t *vpx_img_wrap(vpx_image_t  *img,
186474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                          vpx_img_fmt_t fmt,
187474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                          unsigned int  d_w,
188474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                          unsigned int  d_h,
189474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                          unsigned int  stride_align,
1906fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org                          unsigned char       *img_data) {
1916fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  /* By setting buf_align = 1, we don't change buffer alignment in this
1926fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org   * function. */
1936fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  return img_alloc_helper(img, fmt, d_w, d_h, 1, stride_align, img_data);
194474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org}
195474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
196474eb7536515fb785e925cc9375d22817c416851hclam@chromium.orgint vpx_img_set_rect(vpx_image_t  *img,
197474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                     unsigned int  x,
198474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                     unsigned int  y,
199474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org                     unsigned int  w,
2006fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org                     unsigned int  h) {
2016fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  unsigned char      *data;
2026fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
2036fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  if (x + w <= img->w && y + h <= img->h) {
2046fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    img->d_w = w;
2056fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    img->d_h = h;
2066fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
2076fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    /* Calculate plane pointers */
2086fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    if (!(img->fmt & VPX_IMG_FMT_PLANAR)) {
2096fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      img->planes[VPX_PLANE_PACKED] =
2106fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org        img->img_data + x * img->bps / 8 + y * img->stride[VPX_PLANE_PACKED];
2116fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    } else {
2126fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      data = img->img_data;
2136fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
2146fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      if (img->fmt & VPX_IMG_FMT_HAS_ALPHA) {
2156fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org        img->planes[VPX_PLANE_ALPHA] =
2166fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org          data + x + y * img->stride[VPX_PLANE_ALPHA];
2176fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org        data += img->h * img->stride[VPX_PLANE_ALPHA];
2186fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      }
2196fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
2206fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      img->planes[VPX_PLANE_Y] = data + x + y * img->stride[VPX_PLANE_Y];
2216fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      data += img->h * img->stride[VPX_PLANE_Y];
2226fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
2236fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      if (!(img->fmt & VPX_IMG_FMT_UV_FLIP)) {
2246fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org        img->planes[VPX_PLANE_U] = data
2256fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org                                   + (x >> img->x_chroma_shift)
2266fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org                                   + (y >> img->y_chroma_shift) * img->stride[VPX_PLANE_U];
2276fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org        data += (img->h >> img->y_chroma_shift) * img->stride[VPX_PLANE_U];
2286fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org        img->planes[VPX_PLANE_V] = data
2296fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org                                   + (x >> img->x_chroma_shift)
2306fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org                                   + (y >> img->y_chroma_shift) * img->stride[VPX_PLANE_V];
2316fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      } else {
2326fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org        img->planes[VPX_PLANE_V] = data
2336fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org                                   + (x >> img->x_chroma_shift)
2346fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org                                   + (y >> img->y_chroma_shift) * img->stride[VPX_PLANE_V];
2356fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org        data += (img->h >> img->y_chroma_shift) * img->stride[VPX_PLANE_V];
2366fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org        img->planes[VPX_PLANE_U] = data
2376fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org                                   + (x >> img->x_chroma_shift)
2386fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org                                   + (y >> img->y_chroma_shift) * img->stride[VPX_PLANE_U];
2396fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      }
240474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org    }
241474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2426fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    return 0;
2436fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  }
2446fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
2456fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  return -1;
246474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org}
247474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2486fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.orgvoid vpx_img_flip(vpx_image_t *img) {
2496fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  /* Note: In the calculation pointer adjustment calculation, we want the
2506fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org   * rhs to be promoted to a signed type. Section 6.3.1.8 of the ISO C99
2516fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org   * standard indicates that if the adjustment parameter is unsigned, the
2526fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org   * stride parameter will be promoted to unsigned, causing errors when
2536fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org   * the lhs is a larger type than the rhs.
2546fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org   */
2556fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  img->planes[VPX_PLANE_Y] += (signed)(img->d_h - 1) * img->stride[VPX_PLANE_Y];
2566fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  img->stride[VPX_PLANE_Y] = -img->stride[VPX_PLANE_Y];
2576fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
2586fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  img->planes[VPX_PLANE_U] += (signed)((img->d_h >> img->y_chroma_shift) - 1)
2596fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org                              * img->stride[VPX_PLANE_U];
2606fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  img->stride[VPX_PLANE_U] = -img->stride[VPX_PLANE_U];
2616fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
2626fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  img->planes[VPX_PLANE_V] += (signed)((img->d_h >> img->y_chroma_shift) - 1)
2636fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org                              * img->stride[VPX_PLANE_V];
2646fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  img->stride[VPX_PLANE_V] = -img->stride[VPX_PLANE_V];
2656fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org
2666fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  img->planes[VPX_PLANE_ALPHA] += (signed)(img->d_h - 1) * img->stride[VPX_PLANE_ALPHA];
2676fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  img->stride[VPX_PLANE_ALPHA] = -img->stride[VPX_PLANE_ALPHA];
268474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org}
269474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2706fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.orgvoid vpx_img_free(vpx_image_t *img) {
2716fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  if (img) {
2726fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    if (img->img_data && img->img_data_owner)
273ace65784417788374f0b19ce5a8abd06c9ccd007johannkoenig@chromium.org      vpx_free(img->img_data);
274474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org
2756fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org    if (img->self_allocd)
2766fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org      free(img);
2776fefe538d859300e7febe78271828198c10f1b52fgalligan@chromium.org  }
278474eb7536515fb785e925cc9375d22817c416851hclam@chromium.org}
279