📄 input.c
字号:
/*!
*************************************************************************************
* \file input.c
*
* \brief
* Input related functions
*
* \author
* Main contributors (see contributors.h for copyright, address and affiliation details)
* - Karsten S黨ring <suehring@hhi.de>
* - Alexis Michael Tourapis <alexismt@ieee.org>
*
*************************************************************************************
*/
#include "contributors.h"
#include <math.h>
#include <time.h>
#include <sys/timeb.h>
#include "global.h"
#include "input.h"
#include "report.h"
unsigned char *buf;
void buf2img_basic ( imgpel** imgX, unsigned char* buf, int size_x, int size_y, int o_size_x, int o_size_y, int symbol_size_in_bytes, int bitshift);
void buf2img_endian ( imgpel** imgX, unsigned char* buf, int size_x, int size_y, int o_size_x, int o_size_y, int symbol_size_in_bytes, int bitshift);
void buf2img_bitshift ( imgpel** imgX, unsigned char* buf, int size_x, int size_y, int o_size_x, int o_size_y, int symbol_size_in_bytes, int bitshift);
void (*buf2img) ( imgpel** imgX, unsigned char* buf, int size_x, int size_y, int o_size_x, int o_size_y, int symbol_size_in_bytes, int bitshift);
/*!
************************************************************************
* \brief
* checks if the System is big- or little-endian
* \return
* 0, little-endian (e.g. Intel architectures)
* 1, big-endian (e.g. SPARC, MIPS, PowerPC)
************************************************************************
*/
void initInput(FrameFormat *source, FrameFormat *output)
{
if (source->bit_depth[0] == output->bit_depth[0] && source->bit_depth[1] == output->bit_depth[1])
{
if (( sizeof(char) != sizeof (imgpel)) && testEndian())
buf2img = buf2img_endian;
else
buf2img = buf2img_basic;
}
else
buf2img = buf2img_bitshift;
}
/*!
************************************************************************
* \brief
* checks if the System is big- or little-endian
* \return
* 0, little-endian (e.g. Intel architectures)
* 1, big-endian (e.g. SPARC, MIPS, PowerPC)
************************************************************************
*/
int testEndian(void)
{
short s;
byte *p;
p=(byte*)&s;
s=1;
return (*p==0);
}
#if (DEBUG_BITDEPTH)
/*!
************************************************************************
* \brief
* Masking to ensure data within appropriate range
************************************************************************
*/
static void MaskMSBs (imgpel** imgX, int mask, int width, int height)
{
int i,j;
for (j=0; j < height; j++)
{
for (i=0; i < width; i++)
{
imgX[j][i]=(imgpel) (imgX[j][i] & mask);
}
}
}
#endif
/*!
************************************************************************
* \brief
* Convert file read buffer to source picture structure
************************************************************************
*/
void buf2img_bitshift ( imgpel** imgX, //!< Pointer to image plane
unsigned char* buf, //!< Buffer for file output
int size_x, //!< horizontal size of picture
int size_y, //!< vertical size of picture
int o_size_x, //!< horizontal size of picture
int o_size_y, //!< vertical size of picture
int symbol_size_in_bytes, //!< number of bytes in file used for one pixel
int bitshift //!< variable for bitdepth expansion
)
{
int i,j;
unsigned short tmp16, ui16;
unsigned long tmp32, ui32;
// This test should be done once.
if (((symbol_size_in_bytes << 3) - bitshift) > (sizeof(imgpel)<< 3))
{
error ("Source picture has higher bit depth than imgpel data type. \nPlease recompile with larger data type for imgpel.", 500);
}
if (testEndian())
{
if (size_x != o_size_x || size_y != o_size_y)
{
error ("Rescaling not supported in big endian architectures. ", 500);
}
// big endian
switch (symbol_size_in_bytes)
{
case 1:
{
for(j = 0; j < o_size_y; j++)
for(i = 0; i < o_size_x; i++)
{
imgX[j][i]= (imgpel) rshift_rnd(buf[i + j*size_x], bitshift);
}
break;
}
case 2:
{
for(j = 0; j < o_size_y; j++)
for(i = 0; i < o_size_x; i++)
{
memcpy(&tmp16, buf+((i+j*size_x)*2), 2);
ui16 = (tmp16 >> 8) | ((tmp16&0xFF)<<8);
imgX[j][i] = (imgpel) rshift_rnd(ui16, bitshift);
}
break;
}
case 4:
{
for(j = 0; j < o_size_y; j++)
for(i = 0; i < o_size_x; i++)
{
memcpy(&tmp32, buf+((i+j*size_x)*4), 4);
ui32 = ((tmp32&0xFF00)<<8) | ((tmp32&0xFF)<<24) | ((tmp32&0xFF0000)>>8) | ((tmp32&0xFF000000)>>24);
imgX[j][i] = (imgpel) rshift_rnd(ui32, bitshift);
}
}
default:
{
error ("reading only from formats of 8, 16 or 32 bit allowed on big endian architecture", 500);
break;
}
}
}
else
{
// little endian
int j_pos;
if (size_x == o_size_x && size_y == o_size_y)
{
for (j = 0; j < o_size_y; j++)
{
j_pos = j*size_x;
for (i = 0; i < o_size_x; i++)
{
ui16=0;
memcpy(&(ui16), buf + ((i + j_pos) * symbol_size_in_bytes), symbol_size_in_bytes);
imgX[j][i] = (imgpel) rshift_rnd(ui16,bitshift);
}
}
}
else
{
int iminwidth = imin(size_x, o_size_x);
int iminheight = imin(size_y, o_size_y);
int dst_offset_x = 0, dst_offset_y = 0;
int offset_x = 0, offset_y = 0; // currently not used
// determine whether we need to center the copied frame or crop it
if ( o_size_x >= size_x )
dst_offset_x = ( o_size_x - size_x ) >> 1;
if (o_size_y >= size_y)
dst_offset_y = ( o_size_y - size_y ) >> 1;
// check copied area to avoid copying memory garbage
// source
iminwidth = ( (offset_x + iminwidth ) > size_x ) ? (size_x - offset_x) : iminwidth;
iminheight = ( (offset_y + iminheight) > size_y ) ? (size_y - offset_y) : iminheight;
// destination
iminwidth = ( (dst_offset_x + iminwidth ) > o_size_x ) ? (o_size_x - dst_offset_x) : iminwidth;
iminheight = ( (dst_offset_y + iminheight) > o_size_y ) ? (o_size_y - dst_offset_y) : iminheight;
for (j=0; j < iminheight; j++)
{
j_pos = (j + offset_y) * size_x + offset_x;
for (i=0; i < iminwidth; i++)
{
ui16=0;
memcpy(&(ui16), buf + ((i + j_pos) * symbol_size_in_bytes), symbol_size_in_bytes);
imgX[j + dst_offset_y][i + dst_offset_x] = (imgpel) rshift_rnd(ui16,bitshift);
}
}
}
}
}
/*!
************************************************************************
* \brief
* Convert file read buffer to source picture structure
************************************************************************
*/
void buf2img_basic ( imgpel** imgX, //!< Pointer to image plane
unsigned char* buf, //!< Buffer for file output
int size_x, //!< horizontal size of picture
int size_y, //!< vertical size of picture
int o_size_x, //!< horizontal size of picture
int o_size_y, //!< vertical size of picture
int symbol_size_in_bytes, //!< number of bytes in file used for one pixel
int dummy //!< dummy variable used for allowing function pointer use
)
{
int i,j;
unsigned char* temp_buf = buf;
if (symbol_size_in_bytes> sizeof(imgpel))
{
error ("Source picture has higher bit depth than imgpel data type. \nPlease recompile with larger data type for imgpel.", 500);
}
if (( sizeof (imgpel) == symbol_size_in_bytes))
{
// imgpel == pixel_in_file -> simple copy
if (size_x == o_size_x && size_y == o_size_y)
memcpy(&imgX[0][0], temp_buf, size_x * size_y * sizeof(imgpel));
else
{
int iminwidth = imin(size_x, o_size_x);
int iminheight = imin(size_y, o_size_y);
int dst_offset_x = 0, dst_offset_y = 0;
int offset_x = 0, offset_y = 0; // currently not used
// determine whether we need to center the copied frame or crop it
if ( o_size_x >= size_x )
dst_offset_x = ( o_size_x - size_x ) >> 1;
if (o_size_y >= size_y)
dst_offset_y = ( o_size_y - size_y ) >> 1;
// check copied area to avoid copying memory garbage
// source
iminwidth = ( (offset_x + iminwidth ) > size_x ) ? (size_x - offset_x) : iminwidth;
iminheight = ( (offset_y + iminheight) > size_y ) ? (size_y - offset_y) : iminheight;
// destination
iminwidth = ( (dst_offset_x + iminwidth ) > o_size_x ) ? (o_size_x - dst_offset_x) : iminwidth;
iminheight = ( (dst_offset_y + iminheight) > o_size_y ) ? (o_size_y - dst_offset_y) : iminheight;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -