/*****************************************************************************
* This file is part of Kvazaar HEVC encoder.
*
* Copyright (C) 2013-2014 Tampere University of Technology and others (see
* COPYING file).
*
* Kvazaar is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation.
*
* Kvazaar is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Kvazaar. If not, see .
****************************************************************************/
/*
* \file
*/
#include "threads.h"
#include "image.h"
#include "strategyselector.h"
#include
#include
#include
#include
#include
#include "sao.h"
/**
* \brief Allocate new image
* \return image pointer
*/
image *image_alloc(const int32_t width, const int32_t height)
{
image *im = MALLOC(image, 1);
unsigned int luma_size = width * height;
unsigned int chroma_size = luma_size / 4;
//Assert that we have a well defined image
assert((width % 2) == 0);
assert((height % 2) == 0);
if (!im) return NULL;
im->width = width;
im->height = height;
im->stride = width;
im->base_image = im;
im->refcount = 1; //We give a reference to caller
//Allocate memory
im->fulldata = MALLOC(pixel, (luma_size + 2*chroma_size));
im->y = im->data[COLOR_Y] = &im->fulldata[0];
im->u = im->data[COLOR_U] = &im->fulldata[luma_size];
im->v = im->data[COLOR_V] = &im->fulldata[luma_size + chroma_size];
return im;
}
/**
* \brief Free memory allocated to picture (if we have no reference left)
* \param pic picture pointer
* \return 1 on success, 0 on failure
*/
int image_free(image * const im)
{
//Either we are the base image, or we should have no references
assert(im->base_image == im || im->refcount == 0);
int32_t new_refcount = ATOMIC_DEC(&(im->base_image->refcount));
if (new_refcount > 0) return 1;
FREE_POINTER(im->fulldata);
//Just to make the program crash when using those values after the free
im->y = im->u = im->v = im->data[COLOR_Y] = im->data[COLOR_U] = im->data[COLOR_V] = NULL;
free(im);
return 1;
}
image *image_make_subimage(image * const orig_image, const unsigned int x_offset, const unsigned int y_offset, const unsigned int width, const unsigned int height)
{
image *im = MALLOC(image, 1);
if (!im) return NULL;
im->base_image = orig_image->base_image;
ATOMIC_INC(&(im->base_image->refcount));
assert(x_offset + width <= orig_image->width);
assert(y_offset + height <= orig_image->height);
//Assert that we have a well defined image
assert((width % 2) == 0);
assert((height % 2) == 0);
assert((x_offset % 2) == 0);
assert((y_offset % 2) == 0);
im->stride = orig_image->stride;
im->refcount = 0; //No references on subimages
im->width = width;
im->height = height;
im->y = im->data[COLOR_Y] = &orig_image->y[x_offset + y_offset * orig_image->stride];
im->u = im->data[COLOR_U] = &orig_image->u[x_offset/2 + y_offset/2 * orig_image->stride/2];
im->v = im->data[COLOR_V] = &orig_image->v[x_offset/2 + y_offset/2 * orig_image->stride/2];
return im;
}