LCOV - code coverage report
Current view: top level - media/libvpx/libvpx/vpx/src - vpx_image.c (source / functions) Hit Total Coverage
Test: output.info Lines: 0 110 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 6 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
       3             :  *
       4             :  *  Use of this source code is governed by a BSD-style license
       5             :  *  that can be found in the LICENSE file in the root of the source
       6             :  *  tree. An additional intellectual property rights grant can be found
       7             :  *  in the file PATENTS.  All contributing project authors may
       8             :  *  be found in the AUTHORS file in the root of the source tree.
       9             :  */
      10             : 
      11             : #include <stdlib.h>
      12             : #include <string.h>
      13             : 
      14             : #include "vpx/vpx_image.h"
      15             : #include "vpx/vpx_integer.h"
      16             : #include "vpx_mem/vpx_mem.h"
      17             : 
      18           0 : static vpx_image_t *img_alloc_helper(vpx_image_t *img, vpx_img_fmt_t fmt,
      19             :                                      unsigned int d_w, unsigned int d_h,
      20             :                                      unsigned int buf_align,
      21             :                                      unsigned int stride_align,
      22             :                                      unsigned char *img_data) {
      23             :   unsigned int h, w, s, xcs, ycs, bps;
      24             :   unsigned int stride_in_bytes;
      25             :   int align;
      26             : 
      27             :   /* Treat align==0 like align==1 */
      28           0 :   if (!buf_align) buf_align = 1;
      29             : 
      30             :   /* Validate alignment (must be power of 2) */
      31           0 :   if (buf_align & (buf_align - 1)) goto fail;
      32             : 
      33             :   /* Treat align==0 like align==1 */
      34           0 :   if (!stride_align) stride_align = 1;
      35             : 
      36             :   /* Validate alignment (must be power of 2) */
      37           0 :   if (stride_align & (stride_align - 1)) goto fail;
      38             : 
      39             :   /* Get sample size for this format */
      40           0 :   switch (fmt) {
      41             :     case VPX_IMG_FMT_RGB32:
      42             :     case VPX_IMG_FMT_RGB32_LE:
      43             :     case VPX_IMG_FMT_ARGB:
      44           0 :     case VPX_IMG_FMT_ARGB_LE: bps = 32; break;
      45             :     case VPX_IMG_FMT_RGB24:
      46           0 :     case VPX_IMG_FMT_BGR24: bps = 24; break;
      47             :     case VPX_IMG_FMT_RGB565:
      48             :     case VPX_IMG_FMT_RGB565_LE:
      49             :     case VPX_IMG_FMT_RGB555:
      50             :     case VPX_IMG_FMT_RGB555_LE:
      51             :     case VPX_IMG_FMT_UYVY:
      52             :     case VPX_IMG_FMT_YUY2:
      53           0 :     case VPX_IMG_FMT_YVYU: bps = 16; break;
      54             :     case VPX_IMG_FMT_I420:
      55             :     case VPX_IMG_FMT_YV12:
      56             :     case VPX_IMG_FMT_VPXI420:
      57           0 :     case VPX_IMG_FMT_VPXYV12: bps = 12; break;
      58             :     case VPX_IMG_FMT_I422:
      59           0 :     case VPX_IMG_FMT_I440: bps = 16; break;
      60           0 :     case VPX_IMG_FMT_I444: bps = 24; break;
      61           0 :     case VPX_IMG_FMT_I42016: bps = 24; break;
      62             :     case VPX_IMG_FMT_I42216:
      63           0 :     case VPX_IMG_FMT_I44016: bps = 32; break;
      64           0 :     case VPX_IMG_FMT_I44416: bps = 48; break;
      65           0 :     default: bps = 16; break;
      66             :   }
      67             : 
      68             :   /* Get chroma shift values for this format */
      69           0 :   switch (fmt) {
      70             :     case VPX_IMG_FMT_I420:
      71             :     case VPX_IMG_FMT_YV12:
      72             :     case VPX_IMG_FMT_VPXI420:
      73             :     case VPX_IMG_FMT_VPXYV12:
      74             :     case VPX_IMG_FMT_I422:
      75             :     case VPX_IMG_FMT_I42016:
      76           0 :     case VPX_IMG_FMT_I42216: xcs = 1; break;
      77           0 :     default: xcs = 0; break;
      78             :   }
      79             : 
      80           0 :   switch (fmt) {
      81             :     case VPX_IMG_FMT_I420:
      82             :     case VPX_IMG_FMT_I440:
      83             :     case VPX_IMG_FMT_YV12:
      84             :     case VPX_IMG_FMT_VPXI420:
      85             :     case VPX_IMG_FMT_VPXYV12:
      86             :     case VPX_IMG_FMT_I42016:
      87           0 :     case VPX_IMG_FMT_I44016: ycs = 1; break;
      88           0 :     default: ycs = 0; break;
      89             :   }
      90             : 
      91             :   /* Calculate storage sizes given the chroma subsampling */
      92           0 :   align = (1 << xcs) - 1;
      93           0 :   w = (d_w + align) & ~align;
      94           0 :   align = (1 << ycs) - 1;
      95           0 :   h = (d_h + align) & ~align;
      96           0 :   s = (fmt & VPX_IMG_FMT_PLANAR) ? w : bps * w / 8;
      97           0 :   s = (s + stride_align - 1) & ~(stride_align - 1);
      98           0 :   stride_in_bytes = (fmt & VPX_IMG_FMT_HIGHBITDEPTH) ? s * 2 : s;
      99             : 
     100             :   /* Allocate the new image */
     101           0 :   if (!img) {
     102           0 :     img = (vpx_image_t *)calloc(1, sizeof(vpx_image_t));
     103             : 
     104           0 :     if (!img) goto fail;
     105             : 
     106           0 :     img->self_allocd = 1;
     107             :   } else {
     108           0 :     memset(img, 0, sizeof(vpx_image_t));
     109             :   }
     110             : 
     111           0 :   img->img_data = img_data;
     112             : 
     113           0 :   if (!img_data) {
     114           0 :     const uint64_t alloc_size = (fmt & VPX_IMG_FMT_PLANAR)
     115           0 :                                     ? (uint64_t)h * s * bps / 8
     116           0 :                                     : (uint64_t)h * s;
     117             : 
     118             :     if (alloc_size != (size_t)alloc_size) goto fail;
     119             : 
     120           0 :     img->img_data = (uint8_t *)vpx_memalign(buf_align, (size_t)alloc_size);
     121           0 :     img->img_data_owner = 1;
     122             :   }
     123             : 
     124           0 :   if (!img->img_data) goto fail;
     125             : 
     126           0 :   img->fmt = fmt;
     127           0 :   img->bit_depth = (fmt & VPX_IMG_FMT_HIGHBITDEPTH) ? 16 : 8;
     128           0 :   img->w = w;
     129           0 :   img->h = h;
     130           0 :   img->x_chroma_shift = xcs;
     131           0 :   img->y_chroma_shift = ycs;
     132           0 :   img->bps = bps;
     133             : 
     134             :   /* Calculate strides */
     135           0 :   img->stride[VPX_PLANE_Y] = img->stride[VPX_PLANE_ALPHA] = stride_in_bytes;
     136           0 :   img->stride[VPX_PLANE_U] = img->stride[VPX_PLANE_V] = stride_in_bytes >> xcs;
     137             : 
     138             :   /* Default viewport to entire image */
     139           0 :   if (!vpx_img_set_rect(img, 0, 0, d_w, d_h)) return img;
     140             : 
     141             : fail:
     142           0 :   vpx_img_free(img);
     143           0 :   return NULL;
     144             : }
     145             : 
     146           0 : vpx_image_t *vpx_img_alloc(vpx_image_t *img, vpx_img_fmt_t fmt,
     147             :                            unsigned int d_w, unsigned int d_h,
     148             :                            unsigned int align) {
     149           0 :   return img_alloc_helper(img, fmt, d_w, d_h, align, align, NULL);
     150             : }
     151             : 
     152           0 : vpx_image_t *vpx_img_wrap(vpx_image_t *img, vpx_img_fmt_t fmt, unsigned int d_w,
     153             :                           unsigned int d_h, unsigned int stride_align,
     154             :                           unsigned char *img_data) {
     155             :   /* By setting buf_align = 1, we don't change buffer alignment in this
     156             :    * function. */
     157           0 :   return img_alloc_helper(img, fmt, d_w, d_h, 1, stride_align, img_data);
     158             : }
     159             : 
     160           0 : int vpx_img_set_rect(vpx_image_t *img, unsigned int x, unsigned int y,
     161             :                      unsigned int w, unsigned int h) {
     162             :   unsigned char *data;
     163             : 
     164           0 :   if (x + w <= img->w && y + h <= img->h) {
     165           0 :     img->d_w = w;
     166           0 :     img->d_h = h;
     167             : 
     168             :     /* Calculate plane pointers */
     169           0 :     if (!(img->fmt & VPX_IMG_FMT_PLANAR)) {
     170           0 :       img->planes[VPX_PLANE_PACKED] =
     171           0 :           img->img_data + x * img->bps / 8 + y * img->stride[VPX_PLANE_PACKED];
     172             :     } else {
     173           0 :       const int bytes_per_sample =
     174           0 :           (img->fmt & VPX_IMG_FMT_HIGHBITDEPTH) ? 2 : 1;
     175           0 :       data = img->img_data;
     176             : 
     177           0 :       if (img->fmt & VPX_IMG_FMT_HAS_ALPHA) {
     178           0 :         img->planes[VPX_PLANE_ALPHA] =
     179           0 :             data + x * bytes_per_sample + y * img->stride[VPX_PLANE_ALPHA];
     180           0 :         data += img->h * img->stride[VPX_PLANE_ALPHA];
     181             :       }
     182             : 
     183           0 :       img->planes[VPX_PLANE_Y] =
     184           0 :           data + x * bytes_per_sample + y * img->stride[VPX_PLANE_Y];
     185           0 :       data += img->h * img->stride[VPX_PLANE_Y];
     186             : 
     187           0 :       if (!(img->fmt & VPX_IMG_FMT_UV_FLIP)) {
     188           0 :         img->planes[VPX_PLANE_U] =
     189           0 :             data + (x >> img->x_chroma_shift) * bytes_per_sample +
     190           0 :             (y >> img->y_chroma_shift) * img->stride[VPX_PLANE_U];
     191           0 :         data += (img->h >> img->y_chroma_shift) * img->stride[VPX_PLANE_U];
     192           0 :         img->planes[VPX_PLANE_V] =
     193           0 :             data + (x >> img->x_chroma_shift) * bytes_per_sample +
     194           0 :             (y >> img->y_chroma_shift) * img->stride[VPX_PLANE_V];
     195             :       } else {
     196           0 :         img->planes[VPX_PLANE_V] =
     197           0 :             data + (x >> img->x_chroma_shift) * bytes_per_sample +
     198           0 :             (y >> img->y_chroma_shift) * img->stride[VPX_PLANE_V];
     199           0 :         data += (img->h >> img->y_chroma_shift) * img->stride[VPX_PLANE_V];
     200           0 :         img->planes[VPX_PLANE_U] =
     201           0 :             data + (x >> img->x_chroma_shift) * bytes_per_sample +
     202           0 :             (y >> img->y_chroma_shift) * img->stride[VPX_PLANE_U];
     203             :       }
     204             :     }
     205           0 :     return 0;
     206             :   }
     207           0 :   return -1;
     208             : }
     209             : 
     210           0 : void vpx_img_flip(vpx_image_t *img) {
     211             :   /* Note: In the calculation pointer adjustment calculation, we want the
     212             :    * rhs to be promoted to a signed type. Section 6.3.1.8 of the ISO C99
     213             :    * standard indicates that if the adjustment parameter is unsigned, the
     214             :    * stride parameter will be promoted to unsigned, causing errors when
     215             :    * the lhs is a larger type than the rhs.
     216             :    */
     217           0 :   img->planes[VPX_PLANE_Y] += (signed)(img->d_h - 1) * img->stride[VPX_PLANE_Y];
     218           0 :   img->stride[VPX_PLANE_Y] = -img->stride[VPX_PLANE_Y];
     219             : 
     220           0 :   img->planes[VPX_PLANE_U] += (signed)((img->d_h >> img->y_chroma_shift) - 1) *
     221           0 :                               img->stride[VPX_PLANE_U];
     222           0 :   img->stride[VPX_PLANE_U] = -img->stride[VPX_PLANE_U];
     223             : 
     224           0 :   img->planes[VPX_PLANE_V] += (signed)((img->d_h >> img->y_chroma_shift) - 1) *
     225           0 :                               img->stride[VPX_PLANE_V];
     226           0 :   img->stride[VPX_PLANE_V] = -img->stride[VPX_PLANE_V];
     227             : 
     228           0 :   img->planes[VPX_PLANE_ALPHA] +=
     229           0 :       (signed)(img->d_h - 1) * img->stride[VPX_PLANE_ALPHA];
     230           0 :   img->stride[VPX_PLANE_ALPHA] = -img->stride[VPX_PLANE_ALPHA];
     231           0 : }
     232             : 
     233           0 : void vpx_img_free(vpx_image_t *img) {
     234           0 :   if (img) {
     235           0 :     if (img->img_data && img->img_data_owner) vpx_free(img->img_data);
     236             : 
     237           0 :     if (img->self_allocd) free(img);
     238             :   }
     239           0 : }

Generated by: LCOV version 1.13