/*
* Copyright (c) 2010 The WebM project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
/****************************************************************************
*
* Module Title : preproc.c
*
* Description : Simple pre-processor.
*
****************************************************************************/
/****************************************************************************
* Header Files
****************************************************************************/
#include "memory.h"
#include "preproc7.h"
#include "vpx_mem/vpx_mem.h"
/****************************************************************************
* Macros
****************************************************************************/
#define FRAMECOUNT 7
#define ROUNDUP32(X) ( ( ( (unsigned long) X ) + 31 )&( 0xFFFFFFE0 ) )
/****************************************************************************
* Imports
****************************************************************************/
extern void vp8_get_processor_flags(int *mmx_enabled, int *xmm_enabled, int *wmt_enabled);
/****************************************************************************
* Exported Global Variables
****************************************************************************/
void (*temp_filter)(pre_proc_instance *ppi, unsigned char *s, unsigned char *d, int bytes, int strength);
void temp_filter_mmx
(
pre_proc_instance *ppi,
unsigned char *s,
unsigned char *d,
int bytes,
int strength
);
void temp_filter_wmt
(
pre_proc_instance *ppi,
unsigned char *s,
unsigned char *d,
int bytes,
int strength
);
/****************************************************************************
*
* ROUTINE : temp_filter_c
*
* INPUTS : pre_proc_instance *ppi : Pointer to pre-processor instance.
* unsigned char *s : Pointer to source frame.
* unsigned char *d : Pointer to destination frame.
* int bytes : Number of bytes to filter.
* int strength : Strength of filter to apply.
*
* OUTPUTS : None.
*
* RETURNS : void
*
* FUNCTION : Performs a closesness adjusted temporarl blur
*
* SPECIAL NOTES : Destination frame can be same as source frame.
*
****************************************************************************/
void temp_filter_c
(
pre_proc_instance *ppi,
unsigned char *s,
unsigned char *d,
int bytes,
int strength
)
{
int byte = 0;
unsigned char *frameptr = ppi->frame_buffer;
if (ppi->frame == 0)
{
do
{
int frame = 0;
do
{
*frameptr = s[byte];
++frameptr;
++frame;
}
while (frame < FRAMECOUNT);
d[byte] = s[byte];
++byte;
}
while (byte < bytes);
}
else
{
int modifier;
int offset = (ppi->frame % FRAMECOUNT);
do
{
int accumulator = 0;
int count = 0;
int frame = 0;
frameptr[offset] = s[byte];
do
{
int pixel_value = *frameptr;
modifier = s[byte];
modifier -= pixel_value;
modifier *= modifier;
modifier >>= strength;
modifier *= 3;
if (modifier > 16)
modifier = 16;
modifier = 16 - modifier;
accumulator += modifier * pixel_value;
count += modifier;
frameptr++;
++frame;
}
while (frame < FRAMECOUNT);
accumulator += (count >> 1);
accumulator *= ppi->fixed_divide[count];
accumulator >>= 16;
d[byte] = accumulator;
++byte;
}
while (byte < bytes);
}
++ppi->frame;
}
/****************************************************************************
*
* ROUTINE : delete_pre_proc
*
* INPUTS : pre_proc_instance *ppi : Pointer to pre-processor instance.
*
* OUTPUTS : None.
*
* RETURNS : void
*
* FUNCTION : Deletes a pre-processing instance.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
void delete_pre_proc(pre_proc_instance *ppi)
{
if (ppi->frame_buffer_alloc)
vpx_free(ppi->frame_buffer_alloc);
ppi->frame_buffer_alloc = 0;
ppi->frame_buffer = 0;
if (ppi->fixed_divide_alloc)
vpx_free(ppi->fixed_divide_alloc);
ppi->fixed_divide_alloc = 0;
ppi->fixed_divide = 0;
}
/****************************************************************************
*
* ROUTINE : init_pre_proc
*
* INPUTS : pre_proc_instance *ppi : Pointer to pre-processor instance.
* int frame_size : Number of bytes in one frame.
*
* OUTPUTS : None.
*
* RETURNS : int: 1 if successful, 0 if failed.
*
* FUNCTION : Initializes prepprocessor instance.
*
* SPECIAL NOTES : None.
*
****************************************************************************/
int init_pre_proc7(pre_proc_instance *ppi, int frame_size)
{
int i;
int mmx_enabled;
int xmm_enabled;
int wmt_enabled;
vp8_get_processor_flags(&mmx_enabled, &xmm_enabled, &wmt_enabled);
if (wmt_enabled)
temp_filter = temp_filter_wmt;
else if (mmx_enabled)
temp_filter = temp_filter_mmx;
else
temp_filter = temp_filter_c;
delete_pre_proc(ppi);
ppi->frame_buffer_alloc = vpx_malloc(32 + frame_size * FRAMECOUNT * sizeof(unsigned char));
if (!ppi->frame_buffer_alloc)
{
delete_pre_proc(ppi);
return 0;
}
ppi->frame_buffer = (unsigned char *) ROUNDUP32(ppi->frame_buffer_alloc);
ppi->fixed_divide_alloc = vpx_malloc(32 + 255 * sizeof(unsigned int));
if (!ppi->fixed_divide_alloc)
{
delete_pre_proc(ppi);
return 0;
}
ppi->fixed_divide = (unsigned int *) ROUNDUP32(ppi->fixed_divide_alloc);
for (i = 1; i < 255; i++)
ppi->fixed_divide[i] = 0x10000 / i;
return 1;
}