/** * Part of HEVC Encoder * By Marko Viitanen ( fador at iki.fi ), Tampere University of Technology, Department of Computer Systems. */ /*! \file picture.c \brief Functions to handle pictures \author Marko Viitanen \date 2012-06 This file contains all the needed functions to handle pictures */ #include #include #include #include "global.h" #include "picture.h" /** \defgroup picture_group Picture handler group * This group contains all picture related stuff * @{ */ /*! \brief Allocate memory for picture_list \param size initial array size \return picture_list pointer, NULL on failure */ picture_list *picture_list_init(int size) { picture_list *list = (picture_list *)malloc(sizeof(picture_list)); list->size = size; if(size > 0) { list->pics = (picture**)malloc(sizeof(picture*)*size); } list->used_size = 0; return list; } /*! \brief Resize picture_list array \param list picture_list pointer \param size new array size \return 1 on success, 0 on failure */ int picture_list_resize(picture_list *list, int size) { unsigned int i; picture** old_pics = NULL; //No need to do anything when resizing to same size if(size == list->size) { return 1; } //Save the old list if(list->used_size > 0) { old_pics = list->pics; } //allocate space for the new list list->pics = (picture**)malloc(sizeof(picture*)*size); //Copy everthing from the old list to the new if needed. if(old_pics != NULL) { for(i = 0; i < list->used_size; i++) { list->pics[i] = old_pics[i]; } free(old_pics); } return 1; } /*! \brief Free memory allocated to the picture_list \param list picture_list pointer \return 1 on success, 0 on failure */ int picture_list_destroy(picture_list *list) { unsigned int i; if(list->used_size > 0) { for(i = 0; i < list->used_size; i++) { picture_destroy(list->pics[i]); } } if(list->size > 0) { free(list->pics); } free(list); return 1; } /*! \brief Free memory allocated to picture \param pic picture pointer \return 1 on success, 0 on failure */ int picture_destroy(picture *pic) { free(pic->uData); free(pic->vData); free(pic->yData); return 1; } /** @} */ // end of group1 #include #define PSNRMAX (255*255) //Calculates image PSNR value double imagePSNR(uint8_t *frame1, uint8_t *frame2, uint32_t x, uint32_t y) { double MSE=0.0; double MSEtemp=0.0; double psnr=0.0; int32_t index; //Calculate MSE for(index=x*y-1;index>=0;index--) { MSEtemp=abs(frame1[index]-frame2[index]); MSE+=MSEtemp*MSEtemp; } MSE/=x*y; //Avoid division by zero if(MSE==0) return 99.0; //The PSNR psnr=10*log10(PSNRMAX/MSE); //Thats it. return psnr; } //Sum of Absolute Difference for block uint32_t SAD(uint8_t *block,uint8_t* block2, uint32_t x, uint32_t y) { uint32_t i; uint32_t sum=0; for(i=0;i=0;y--) { i = y*stride1; ii = y*stride2; sum+=abs((int32_t)block[i]-(int32_t)block2[ii]); sum+=abs((int32_t)block[i-1]-(int32_t)block2[ii-1]); sum+=abs((int32_t)block[i-2]-(int32_t)block2[ii-2]); sum+=abs((int32_t)block[i-3]-(int32_t)block2[ii-3]); sum+=abs((int32_t)block[i-4]-(int32_t)block2[ii-4]); sum+=abs((int32_t)block[i-5]-(int32_t)block2[ii-5]); sum+=abs((int32_t)block[i-6]-(int32_t)block2[ii-6]); sum+=abs((int32_t)block[i-7]-(int32_t)block2[ii-7]); sum+=abs((int32_t)block[i-8]-(int32_t)block2[ii-8]); sum+=abs((int32_t)block[i-9]-(int32_t)block2[ii-9]); sum+=abs((int32_t)block[i-10]-(int32_t)block2[ii-10]); sum+=abs((int32_t)block[i-11]-(int32_t)block2[ii-11]); sum+=abs((int32_t)block[i-12]-(int32_t)block2[ii-12]); sum+=abs((int32_t)block[i-13]-(int32_t)block2[ii-13]); sum+=abs((int32_t)block[i-14]-(int32_t)block2[ii-14]); sum+=abs((int32_t)block[i-15]-(int32_t)block2[ii-15]); sum+=abs((int32_t)block[i-16]-(int32_t)block2[ii-16]); sum+=abs((int32_t)block[i-17]-(int32_t)block2[ii-17]); sum+=abs((int32_t)block[i-18]-(int32_t)block2[ii-18]); sum+=abs((int32_t)block[i-19]-(int32_t)block2[ii-19]); sum+=abs((int32_t)block[i-20]-(int32_t)block2[ii-20]); sum+=abs((int32_t)block[i-21]-(int32_t)block2[ii-21]); sum+=abs((int32_t)block[i-22]-(int32_t)block2[ii-22]); sum+=abs((int32_t)block[i-23]-(int32_t)block2[ii-23]); sum+=abs((int32_t)block[i-24]-(int32_t)block2[ii-24]); sum+=abs((int32_t)block[i-25]-(int32_t)block2[ii-25]); sum+=abs((int32_t)block[i-26]-(int32_t)block2[ii-26]); sum+=abs((int32_t)block[i-27]-(int32_t)block2[ii-27]); sum+=abs((int32_t)block[i-28]-(int32_t)block2[ii-28]); sum+=abs((int32_t)block[i-29]-(int32_t)block2[ii-29]); sum+=abs((int32_t)block[i-30]-(int32_t)block2[ii-30]); sum+=abs((int32_t)block[i-31]-(int32_t)block2[ii-31]); } return sum; } uint32_t SAD16x16(int16_t *block,uint32_t stride1,int16_t* block2, uint32_t stride2) { int32_t i,ii,y; uint32_t sum=0; for(y=16-1;y>=0;y--) { i = y*stride1; ii = y*stride2; sum+=abs((int32_t)block[i]-(int32_t)block2[ii]); sum+=abs((int32_t)block[i-1]-(int32_t)block2[ii-1]); sum+=abs((int32_t)block[i-2]-(int32_t)block2[ii-2]); sum+=abs((int32_t)block[i-3]-(int32_t)block2[ii-3]); sum+=abs((int32_t)block[i-4]-(int32_t)block2[ii-4]); sum+=abs((int32_t)block[i-5]-(int32_t)block2[ii-5]); sum+=abs((int32_t)block[i-6]-(int32_t)block2[ii-6]); sum+=abs((int32_t)block[i-7]-(int32_t)block2[ii-7]); sum+=abs((int32_t)block[i-8]-(int32_t)block2[ii-8]); sum+=abs((int32_t)block[i-9]-(int32_t)block2[ii-9]); sum+=abs((int32_t)block[i-10]-(int32_t)block2[ii-10]); sum+=abs((int32_t)block[i-11]-(int32_t)block2[ii-11]); sum+=abs((int32_t)block[i-12]-(int32_t)block2[ii-12]); sum+=abs((int32_t)block[i-13]-(int32_t)block2[ii-13]); sum+=abs((int32_t)block[i-14]-(int32_t)block2[ii-14]); sum+=abs((int32_t)block[i-15]-(int32_t)block2[ii-15]); sum+=abs((int32_t)block[i-16]-(int32_t)block2[ii-16]); } return sum; }