我正在使用以下代码来扩展jpeg,我从互联网上的一个例子中得到了ZoomOutJpeg()函数。
//JpegLib Error Handing - Begin
struct my_error_mgr
{
struct jpeg_error_mgr pub; /* "public" fields */
jmp_buf setjmp_buffer; /* for return to caller */
};
typedef struct my_error_mgr * my_error_ptr;
/*
* Here's the routine that will replace the standard error_exit method:
*/
METHODDEF(void)
my_error_exit(j_common_ptr cinfo)
{
/* cinfo->err really points to a my_error_mgr struct, so coerce pointer */
my_error_ptr myerr = (my_error_ptr)cinfo->err;
/* Always display the message. */
/* We could postpone this until after returning, if we chose. */
(*cinfo->err->output_message) (cinfo);
/* Return control to the setjmp point */
longjmp(myerr->setjmp_buffer, 1);
}
//JpegLib Error Handing - End
/*
* zoom out picture. the factor should between 0.5 and 1.0. It can be 0.5, but can not be 1.0.
*/
bool ZoomOutJpeg(UINT8 *inBuff, UINT8 *outBuff, UINT32 inSize, UINT32* _outSize, float factor)
{
//if (factor > 1 || factor < 0.5f)
// return false;
// init decompress struct
struct jpeg_decompress_struct in;
JSAMPROW inRowPointer[1];
// init compress struct
struct jpeg_compress_struct out;
JSAMPROW outRowPointer[1];
struct my_error_mgr jerrIn;
struct my_error_mgr jerrOut;
/* We set up the normal JPEG error routines, then override error_exit. */
in.err = jpeg_std_error(&jerrIn.pub);
jerrIn.pub.error_exit = my_error_exit;
/* Establish the setjmp return context for my_error_exit to use. */
if (setjmp(jerrIn.setjmp_buffer))
{
jpeg_destroy_decompress(&in);
return false;
}
jpeg_create_decompress(&in);
jpeg_mem_src(&in, inBuff, inSize);
jpeg_read_header(&in, TRUE);
jpeg_start_decompress(&in);
out.err = jpeg_std_error(&jerrOut.pub);
jerrOut.pub.error_exit = my_error_exit;
/* Establish the setjmp return context for my_error_exit to use. */
if (setjmp(jerrOut.setjmp_buffer))
{
jpeg_destroy_decompress(&in);
jpeg_destroy_compress(&out);
return false;
}
jpeg_create_compress(&out);
jpeg_mem_dest(&out, &outBuff, (unsigned long*)_outSize);
int width = in.output_width;
int height = in.output_height;
int bytesPerPixel = in.num_components;
int destWidth = (int)(width * factor);
int destHeight = (int)(height * factor);
_outFrameSize->resX = destWidth;
_outFrameSize->resY = destHeight;
out.image_width = destWidth;
out.image_height = destHeight;
out.input_components = bytesPerPixel;
out.in_color_space = JCS_RGB;
jpeg_set_defaults(&out);
jpeg_start_compress(&out, TRUE);
// Process RGB data.
int outRowStride = destWidth * bytesPerPixel;
int inRowStride = width * bytesPerPixel;
outRowPointer[0] = (unsigned char *)malloc(outRowStride);
inRowPointer[0] = (unsigned char *)malloc(inRowStride);
JSAMPROW baseInRowPointer[1];
baseInRowPointer[0] = (unsigned char *)malloc(inRowStride);
unsigned char bUpLeft, bUpRight, bDownLeft, bDownRight;
unsigned char gUpLeft, gUpRight, gDownLeft, gDownRight;
unsigned char rUpLeft, rUpRight, rDownLeft, rDownRight;
unsigned char b, g, r;
float fX, fY;
int iX, iY;
int i, j;
int currentBaseLocation = -1;
int count = 0;
// Process the first line.
jpeg_read_scanlines(&in, inRowPointer, 1);
for (j = 0; j < destWidth; j++)
{
fX = ((float)j) / factor;
iX = (int)fX;
bUpLeft = inRowPointer[0][iX * 3 + 0];
bUpRight = inRowPointer[0][(iX + 1) * 3 + 0];
gUpLeft = inRowPointer[0][iX * 3 + 1];
gUpRight = inRowPointer[0][(iX + 1) * 3 + 1];
rUpLeft = inRowPointer[0][iX * 3 + 2];
rUpRight = inRowPointer[0][(iX + 1) * 3 + 2];
b = bUpLeft * (iX + 1 - fX) + bUpRight * (fX - iX);
g = gUpLeft * (iX + 1 - fX) + gUpRight * (fX - iX);
r = rUpLeft * (iX + 1 - fX) + rUpRight * (fX - iX);
outRowPointer[0][j * 3 + 0] = b;
outRowPointer[0][j * 3 + 1] = g;
outRowPointer[0][j * 3 + 2] = r;
}
jpeg_write_scanlines(&out, outRowPointer, 1);
currentBaseLocation = 0;
//Process the other lines between the first and last.
for (i = 1; i < destHeight - 1; i++)
{
fY = ((float)i) / factor;
iY = (int)fY;
if (iY == currentBaseLocation)
{
in.output_scanline = iY;
SwapJsampRow(inRowPointer[0], baseInRowPointer[0]);
jpeg_read_scanlines(&in, baseInRowPointer, 1);
}
else
{
in.output_scanline = iY - 1;
jpeg_read_scanlines(&in, inRowPointer, 1);
jpeg_read_scanlines(&in, baseInRowPointer, 1);
}
currentBaseLocation = iY + 1;
for (j = 0; j < destWidth; j++)
{
fX = ((float)j) / factor;
iX = (int)fX;
bUpLeft = inRowPointer[0][iX * 3 + 0];
bUpRight = inRowPointer[0][(iX + 1) * 3 + 0];
bDownLeft = baseInRowPointer[0][iX * 3 + 0];
bDownRight = baseInRowPointer[0][(iX + 1) * 3 + 0];
gUpLeft = inRowPointer[0][iX * 3 + 1];
gUpRight = inRowPointer[0][(iX + 1) * 3 + 1];
gDownLeft = baseInRowPointer[0][iX * 3 + 1];
gDownRight = baseInRowPointer[0][(iX + 1) * 3 + 1];
rUpLeft = inRowPointer[0][iX * 3 + 2];
rUpRight = inRowPointer[0][(iX + 1) * 3 + 2];
rDownLeft = baseInRowPointer[0][iX * 3 + 2];
rDownRight = baseInRowPointer[0][(iX + 1) * 3 + 2];
b = bUpLeft * (iX + 1 - fX) * (iY + 1 - fY) + bUpRight * (fX - iX) * (iY + 1 - fY) + bDownLeft * (iX + 1 - fX) * (fY - iY) + bDownRight * (fX - iX) * (fY - iY);
g = gUpLeft * (iX + 1 - fX) * (iY + 1 - fY) + gUpRight * (fX - iX) * (iY + 1 - fY) + gDownLeft * (iX + 1 - fX) * (fY - iY) + gDownRight * (fX - iX) * (fY - iY);
r = rUpLeft * (iX + 1 - fX) * (iY + 1 - fY) + rUpRight * (fX - iX) * (iY + 1 - fY) + rDownLeft * (iX + 1 - fX) * (fY - iY) + rDownRight * (fX - iX) * (fY - iY);
outRowPointer[0][j * 3 + 0] = b;
outRowPointer[0][j * 3 + 1] = g;
outRowPointer[0][j * 3 + 2] = r;
}
jpeg_write_scanlines(&out, outRowPointer, 1);
}
//Process the last line.
in.output_scanline = height - 1;
jpeg_read_scanlines(&in, inRowPointer, 1);
for (j = 0; j < destWidth; j++)
{
fX = ((float)j) / factor;
iX = (int)fX;
bUpLeft = inRowPointer[0][iX * 3 + 0];
bUpRight = inRowPointer[0][(iX + 1) * 3 + 0];
gUpLeft = inRowPointer[0][iX * 3 + 1];
gUpRight = inRowPointer[0][(iX + 1) * 3 + 1];
rUpLeft = inRowPointer[0][iX * 3 + 2];
rUpRight = inRowPointer[0][(iX + 1) * 3 + 2];
b = bUpLeft * (iX + 1 - fX) + bUpRight * (fX - iX);
g = gUpLeft * (iX + 1 - fX) + gUpRight * (fX - iX);
r = rUpLeft * (iX + 1 - fX) + rUpRight * (fX - iX);
outRowPointer[0][j * 3 + 0] = b;
outRowPointer[0][j * 3 + 1] = g;
outRowPointer[0][j * 3 + 2] = r;
}
jpeg_write_scanlines(&out, outRowPointer, 1);
//free memory
free(inRowPointer[0]);
free(baseInRowPointer[0]);
free(outRowPointer[0]);
// close resource
jpeg_finish_decompress(&in);
jpeg_destroy_decompress(&in);
jpeg_finish_compress(&out);
jpeg_destroy_compress(&out);
return true;
}
我对上面的代码有一些疑问:
我不明白为什么作者说"zoom out picture. the factor should between 0.5 and 1.0. It can be 0.5, but can not be 1.0."
如果我将此代码与0.2
或2
(放大)等任何其他因素一起使用会怎样?
我在下面的错误处理中使用jpeg_destroy_decompress(&in); jpeg_destroy_compress(&out);
时是否存在任何潜在问题?
当我使用因果为ZoomOutJpeg()
的{{1}}时,通常会出现错误,并且结果图像已损坏。我该如何解决它,我真的想用任何因子进行缩放。
最后,如果有人有任何其他算法或库来扩展jpeg,那么性能最佳,请介绍我。
非常感谢!
T&amp; T公司
答案 0 :(得分:0)