📄 jpeg.c
字号:
#ifdef __WIN32__
offset -= 3*i+nExtra*nValidHigh;
#else
offset += 3 * i ;
#endif
index[0] = pYBuf ;
index[1] = pCbBuf ;
index[2] = pCrBuf ;
nCurHeight += nValidHigh;
nCurWidth = 0 ;
//
// return image data to callback function
if (++stripsCount >= StripsForCallback) {
pCallbackParam -> lStartLine = lastHeight ;
if (nCurHeight < lHeight) {
pCallbackParam -> lLineCount= (MLong)nCurHeight - lastHeight ;
lastHeight = nCurHeight ;
}
else {
pCallbackParam -> lLineCount= (MLong)lHeight - lastHeight ;
lastHeight = lHeight;
bTerminated = MTrue;
}
if ( !CALL_CALLBACK_FUNCTION( lpProc , pCallbackParam ) ) {
releaseReturn = NO_ENOUGH_MEMORY;
goto releaseReturn2;
}
pDecolorParam -> outRGB = pCallbackParam -> pBuffer ;
offset = 0 ;
stripsCount = 0 ;
}
/////////////////////////
// if (CinHigh>=32)
// break;
//////////////////////////
}
run = DECODE_JPEG_OK ;
if ((nCurHeight >= lHeight) || (bTerminated)) {
breakWhile:
if (stripsCount > 0 ) {
pCallbackParam -> lStartLine = lastHeight ;
if (nCurHeight > lHeight)
pCallbackParam -> lLineCount = (MLong)lHeight - lastHeight ;
else
pCallbackParam -> lLineCount = (MLong)nCurHeight - lastHeight ;
if ( !CALL_CALLBACK_FUNCTION( lpProc , pCallbackParam ) ) {
releaseReturn = NO_ENOUGH_MEMORY;
goto releaseReturn2;
}
}
break ;
}
}
//
// clean up output data to callback function
pCallbackParam -> lStatus = JPG_CALLBACK_END ;
pCallbackParam -> lLineCount = 0 ;
if ( !CALL_CALLBACK_FUNCTION( lpProc , pCallbackParam ) ) {
releaseReturn = NO_ENOUGH_MEMORY;
}
releaseReturn2:
JpegMemFree(pYBuf);
JpegMemFree(pCbBuf) ;
JpegMemFree(pCrBuf) ;
JpegMemFree(pYResampled) ;
JpegMemFree(pCbResampled) ;
JpegMemFree(pCrResampled) ;
releaseReturn3:
JpegMemFree(pDecoderInfo) ;
if ( pDecolorParam ) {
JpegMemFree( pDecolorParam -> COE_Cr ) ;
JpegMemFree( pDecolorParam -> COE_Cb ) ;
JpegMemFree(pDecolorParam) ;
}
JpegMemFree( pCallbackParam ) ;
if ( hJpeg ) {
releaseJpegHandle( hJpeg ) ;
}
return releaseReturn ;
}
}
/////////////////////////////////////////////////////
int GetInfo(JPEG_HANDLE *hJpeg, HMSTREAM stream_handle, LPJPG_INFO pJpgInfo) {
MLong buf_len;
if ( hJpeg -> fileSize > JPEG_BUFFER_LEN ) {
buf_len = JPEG_BUFFER_LEN ;
hJpeg -> buffer = ( MByte * ) AMMemAlloc ( MNull, JPEG_BUFFER_LEN + 1 ) ;
if ( !hJpeg -> buffer ) {
return NO_ENOUGH_MEMORY ;
}
hJpeg -> restBlock = ( hJpeg -> fileSize - DECODE_BUFFER_LEN - 1 ) / ( JPEG_BUFFER_LEN - DECODE_BUFFER_LEN ) ;
}
else {
buf_len = hJpeg -> fileSize ;
hJpeg -> buffer = ( MByte * ) AMMemAlloc ( MNull, buf_len ) ;
if ( !hJpeg -> buffer ) {
return NO_ENOUGH_MEMORY ;
}
hJpeg -> restBlock = 0 ;
}
hJpeg -> bufferLen = AMStreamRead(stream_handle,hJpeg -> buffer, buf_len);
if ( hJpeg -> bufferLen <= 0 ) {
return READ_IMAGE_ERROR ;
}
if ( hJpeg -> restBlock > 0 ) {
hJpeg -> pStream = stream_handle ;
}
hJpeg -> decodeStatus = DECODING_JPEG ;
hJpeg -> pJpegInfo = ( JPEG_DECODER_INFO * ) AMMemAlloc ( MNull, sizeof ( JPEG_DECODER_INFO ) ) ;
if ( !hJpeg -> pJpegInfo ) {
return NO_ENOUGH_MEMORY ;
}
hJpeg -> pInfo = hJpeg -> pJpegInfo ;
AMMemSet( hJpeg -> pJpegInfo, 0 , sizeof ( JPEG_DECODER_INFO ) ) ;
if ( JPG_ReadHead( hJpeg ) == READ_JPEG_OK ) {
if ( hJpeg -> pJpegInfo -> type == JPEG_TYPE_JFIF ) {
hJpeg -> decodeStatus = DECODING_THUMBNAIL ;
JPG_ReadJfifHead( hJpeg ) ;
}
else if ( hJpeg -> pJpegInfo -> type == JPEG_TYPE_EXIF ) {
hJpeg -> decodeStatus = DECODING_THUMBNAIL ;
JPG_ReadExifHead( hJpeg ) ;
}
if (pJpgInfo) {
pJpgInfo->lWidth = hJpeg -> pJpegInfo -> Width ;
pJpgInfo->lHeight = hJpeg -> pJpegInfo -> Height ;
pJpgInfo->colorBits = hJpeg -> pJpegInfo -> colorBits ;
}
}
else {
return UNKNOW_THIS_FORMAT_ERROR ;
}
return READ_JPEG_OK ;
}
int OpenFileAndGetInfo( JPEG_HANDLE *hJpeg, HMSTREAM stream_handle ) {
int run ;
if ( ( hJpeg -> fileSize = AMStreamGetSize( stream_handle ) ) <= 0 ) {
return READ_IMAGE_ERROR ;
}
if ( ( run = GetInfo( hJpeg, stream_handle, MNull ) ) != READ_JPEG_OK )
return run ;
if ( ( hJpeg -> pJpegInfo == MNull ) || ( hJpeg -> buffer == MNull ) )
return NO_ENOUGH_MEMORY ;
hJpeg -> pInfo = hJpeg -> pJpegInfo ;
hJpeg -> pInfo -> CurrentData= hJpeg -> buffer[hJpeg -> jpegBeginPos] ;
hJpeg -> pInfo -> bitPos = 8 ;
if ( hJpeg -> buffer[hJpeg -> jpegBeginPos] == 0xff ) {
if ( hJpeg -> buffer[hJpeg -> jpegBeginPos + 1] == 0x00 )
hJpeg -> pInfo -> dataPos = hJpeg -> jpegBeginPos + 2 ;
else
return READ_IMAGE_ERROR ;
}
else
hJpeg -> pInfo -> dataPos = hJpeg -> jpegBeginPos + 1 ;
return READ_JPEG_OK ;
}
int getColorLimitTable( JPEG_HANDLE *hJpeg ) {
int i;
if ( hJpeg -> ColorLimitTable == MNull )
{
hJpeg -> ColorLimitTable = (MByte *) AMMemAlloc(MNull, 2*INDEX_COLOR_TABLE + 256 ) ;
if (!hJpeg -> ColorLimitTable)
return NO_ENOUGH_MEMORY ;
AMMemSet(hJpeg -> ColorLimitTable, 0, INDEX_COLOR_TABLE ) ;
AMMemSet(&hJpeg -> ColorLimitTable[INDEX_COLOR_TABLE + 256], 255, INDEX_COLOR_TABLE ) ;
for (i = INDEX_COLOR_TABLE ; i < ( INDEX_COLOR_TABLE + 256 ) ; i++ )
hJpeg -> ColorLimitTable[i] = i - INDEX_COLOR_TABLE ;
}
return READ_JPEG_OK ;
}
void InitHuffmanVar( JPEG_HANDLE *hJpeg ) {
int i;
hJpeg -> shiftN[0] = 0 ;
hJpeg -> huffBitOffset[0] = 0 ;
hJpeg -> huffMaskOffset[0] = 0 ;
for ( i = 1; i < 16; i ++ ) {
hJpeg -> shiftN[i] = ( ( -1 ) << i ) + 1 ;
hJpeg -> huffBitOffset[i] = 1 << ( i - 1 ) ;
hJpeg -> huffMaskOffset[i] = hJpeg -> huffMaskOffset[i - 1] | hJpeg -> huffBitOffset[i] ;
}
}
int InitResampleVar( JPEG_HANDLE *hJpeg, int lWidth, int lHeight ) {
int i, j, run ;
int Height = hJpeg -> pInfo -> Height ;
int Width = hJpeg -> pInfo -> Width ;
hJpeg -> resamleAddrH = ( MShort * ) AMMemAlloc(MNull, lHeight * sizeof( MShort ) ) ;
hJpeg -> resamleAddrW = ( MShort * ) AMMemAlloc(MNull, lWidth * sizeof( MShort ) ) ;
hJpeg -> newHBegin = ( MShort * ) AMMemAlloc(MNull, ( Height + 16 ) * sizeof( MShort ) ) ;
hJpeg -> newHEnd = ( MShort * ) AMMemAlloc(MNull, ( Height + 16 ) * sizeof( MShort ) ) ;
if ( !hJpeg -> resamleAddrH || !hJpeg -> resamleAddrW || !hJpeg -> newHBegin || !hJpeg -> newHEnd )
return NO_ENOUGH_MEMORY ;
AMMemSet(hJpeg -> newHBegin, 0, Height * sizeof( MShort ) ) ;
AMMemSet(hJpeg -> newHEnd, 0, Height * sizeof( MShort ) ) ;
j = lWidth >> 1 ;
for ( i = 0; i < lWidth; i ++ ) {
hJpeg -> resamleAddrW[i] = (MShort)(( Width * i + j ) / lWidth) ;
if (hJpeg -> resamleAddrW[i] >= Width )
hJpeg -> resamleAddrW[i] = (MShort)(Width - 1) ;
}
j = lHeight >> 1 ;
for ( i = 0; i < lHeight; i ++ ) {
hJpeg -> resamleAddrH[i] = (MShort)(( Height * i + j ) / lHeight) ;
if (hJpeg -> resamleAddrH[i] >= Height )
hJpeg -> resamleAddrH[i] = (MShort)(Height - 1) ;
hJpeg -> newHBegin[hJpeg -> resamleAddrH[i]] = i ;
}
for ( i = ( hJpeg -> resamleAddrH[lHeight - 1] + 1 ); i < ( Height + 16 ); i ++ ) {
hJpeg -> newHBegin[i] = lHeight - 1 ;
}
j = hJpeg -> newHBegin[0] ;
for (i = 0; i < ( Height + 16 ); i ++ ) {
if ( hJpeg -> newHBegin[i] != 0 )
j = hJpeg -> newHBegin[i] ;
else
hJpeg -> newHBegin[i] = j ;
}
for ( i = ( Height - 1 ); i < ( Height + 16 ); i ++ ) {
hJpeg -> newHEnd[i] = lHeight - 1 ;
}
j = hJpeg -> newHBegin[Height - 1] ;
for (i = ( Height - 2 ); i >= 0 ; i -- ) {
if ( j > hJpeg -> newHBegin[i] ) {
hJpeg -> newHEnd[i] = j - 1 ;
j = hJpeg -> newHBegin[i] ;
}
else {
hJpeg -> newHEnd[i] = j ;
}
}
if ( hJpeg -> pInfo -> HighSamp[0] == 2 ) {
hJpeg -> resamleAddrH2 = ( MShort * ) AMMemAlloc(MNull, lHeight * sizeof( MShort ) ) ;
hJpeg -> newH2Begin = ( MShort * ) AMMemAlloc(MNull, ((Height >> 1) + 17 ) * sizeof( MShort ) ) ;
hJpeg -> newH2End = ( MShort * ) AMMemAlloc(MNull, ((Height >> 1) + 17 ) * sizeof( MShort ) ) ;
if ( !hJpeg -> resamleAddrH2 || !hJpeg -> newH2Begin || !hJpeg -> newH2End )
return NO_ENOUGH_MEMORY ;
AMMemSet(hJpeg -> newH2Begin, 0, ((Height >> 1) + 1 ) * sizeof( MShort ) ) ;
AMMemSet(hJpeg -> newH2End, 0, ((Height >> 1) + 1 ) * sizeof( MShort ) ) ;
j = 0 ;
run = ( Height + 1 ) >> 1 ;
for ( i = 0; i < lHeight; i ++ ) {
hJpeg -> resamleAddrH2[i] = (MShort)( hJpeg -> resamleAddrH[i] >> 1 ) ;
if (hJpeg -> resamleAddrH2[i] >= run )
hJpeg -> resamleAddrH2[i] = run - 1 ;
if ( j == hJpeg -> resamleAddrH2[i] ) {
hJpeg -> newH2Begin[hJpeg -> resamleAddrH2[i]] = hJpeg -> newH2Begin[j] ;
}
else {
hJpeg -> newH2Begin[hJpeg -> resamleAddrH2[i]] = i ;
}
j = hJpeg -> resamleAddrH2[i] ;
}
for ( i = ( hJpeg -> resamleAddrH2[lHeight - 1] + 1 ); i < ((Height >> 1) + 17 ); i ++ ) {
hJpeg -> newH2Begin[i] = lHeight - 1 ;
}
j = hJpeg -> newH2Begin[0] ;
for (i = 0; i < ((Height >> 1) + 17 ); i ++ ) {
if ( hJpeg -> newH2Begin[i] != 0 )
j = hJpeg -> newH2Begin[i] ;
else
hJpeg -> newH2Begin[i] = j ;
}
for ( i = ((Height >> 1) - 1 ); i < ((Height >> 1) + 17 ); i ++ ) {
hJpeg -> newH2End[i] = lHeight - 1 ;
}
j = hJpeg -> newH2Begin[( Height + 1 ) >> 1] ;
for (i = ( ( Height - 1 ) >> 1 ); i >= 0 ; i -- ) {
if ( j > hJpeg -> newH2Begin[i] ) {
hJpeg -> newH2End[i] = j - 1 ;
j = hJpeg -> newH2Begin[i] ;
}
else {
hJpeg -> newH2End[i] = j ;
}
}
}
if ( hJpeg -> pInfo -> WideSamp[0] == 2 ) {
hJpeg -> resamleAddrW2 = ( MShort * ) AMMemAlloc(MNull, lWidth * sizeof( MShort ) ) ;
if ( !hJpeg -> resamleAddrW2 )
return NO_ENOUGH_MEMORY ;
run = ( Width + 1 ) >> 1 ;
for ( i = 0; i < lWidth; i ++ ) {
hJpeg -> resamleAddrW2[i] = (MShort) (hJpeg -> resamleAddrW[i] >> 1 ) ;
if (hJpeg -> resamleAddrW2[i] >= run )
hJpeg -> resamleAddrW2[i] = run - 1 ;
}
}
return READ_JPEG_OK ;
}
int hJpegInit( JPEG_HANDLE **hJpeg, HMSTREAM stream_handle, MLong *lWidth, MLong *lHeight ) {
int Height ;
int Width ;
int run ;
*hJpeg = ( JPEG_HANDLE * ) AMMemAlloc ( MNull, sizeof ( JPEG_HANDLE ) ) ;
if ( !*hJpeg )
return NO_ENOUGH_MEMORY ;
AMMemSet( *hJpeg, 0 , sizeof ( JPEG_HANDLE ) ) ;
if ( ( run = OpenFileAndGetInfo(*hJpeg, stream_handle ) ) != READ_JPEG_OK )
return run ;
if ( ( run = getColorLimitTable( *hJpeg ) ) != READ_JPEG_OK )
return run ;
InitHuffmanVar( *hJpeg ) ;
Height = (*hJpeg) -> pInfo -> Height ;
Width = (*hJpeg) -> pInfo -> Width ;
if ( ( *lWidth <= 0 ) || ( *lHeight <= 0 ) ) {
*lWidth = Width ;
*lHeight = Height ;
}
else {
if ( ( Width > *lWidth ) || ( Height > *lHeight ) ) {
if ( ( *lWidth * Height ) >= ( *lHeight * Width ) ){
*lWidth = ( *lHeight * Width ) / Height ;
if (*lWidth == 0)
*lWidth = 1;
}
else {
*lHeight= ( *lWidth * Height ) / Width ;
if (*lHeight == 0)
*lHeight = 1;
}
}
else {
*lWidth = Width ;
*lHeight = Height ;
}
}
if ( ( run = InitResampleVar( *hJpeg, *lWidth, *lHeight ) ) != READ_JPEG_OK )
return run ;
return READ_JPEG_OK ;
}
int huffmanDecodeInfoInit( JPEG_HANDLE *hJpeg, HUFFMAN_QT_DECODER_INFO ** pDecoderInfo ) {
int i, run ;
*pDecoderInfo = ( HUFFMAN_QT_DECODER_INFO * ) AMMemAlloc(MNull, sizeof( HUFFMAN_QT_DECODER_INFO ) ) ;
if ( !*pDecoderInfo )
return NO_ENOUGH_MEMORY ;
(*pDecoderInfo) -> HuffTabNum = hJpeg -> pInfo -> HuffTabNum ;
(*pDecoderInfo) -> WideSamp = hJpeg -> pInfo -> WideSamp ;
(*pDecoderInfo) -> HighSamp = hJpeg -> pInfo -> HighSamp ;
(*pDecoderInfo) -> dataPos = hJpeg -> pInfo -> dataPos ;
(*pDecoderInfo) -> bitPos = hJpeg -> pInfo -> bitPos ;
(*pDecoderInfo) -> CurrentData = hJpeg -> pInfo -> CurrentData ;
for( run = (*pDecoderInfo) -> HuffTabNum - 1 ; run >= 0 ; run -- ) {
i = hJpeg -> pInfo -> qtID[run] ;
(*pDecoderInfo) -> Qtab[run] = hJpeg -> pInfo -> Qtab[i] ;
i = hJpeg -> pInfo -> hufAcID[run] ;
(*pDecoderInfo) -> HufAcTail[run] = hJpeg -> pInfo -> HufAcTail[i] ;
(*pDecoderInfo) -> HufAcOffset[run] = hJpeg -> pInfo -> HufAcOffset[i] ;
(*pDecoderInfo) -> HufTabAc[run] = hJpeg -> pInfo -> HufTabAc[i] ;
(*pDecoderInfo) -> minAcBits[run] = hJpeg -> pInfo -> minAcBits[i] ;
i = hJpeg -> pInfo -> hufDcID[run] ;
(*pDecoderInfo) -> HufDcTail[run] = hJpeg -> pInfo -> HufDcTail[i] ;
(*pDecoderInfo) -> HufDcOffset[run] = hJpeg -> pInfo -> HufDcOffset[i] ;
(*pDecoderInfo) -> HufTabDc[run] = hJpeg -> pInfo -> HufTabDc[i] ;
(*pDecoderInfo) -> minDcBits[run] = hJpeg -> pInfo -> minDcBits[i] ;
}
return READ_JPEG_OK ;
}
int colorInfoInit( JPEG_HANDLE *hJpeg, DECOLOR_PARAM ** pDecolorParam, JPG_CALLBACK_PARAM *pCallbackParam, int lWidth ) {
int i ;
*pDecolorParam = ( LPDECOLOR_PARAM )AMMemAlloc( MNull, sizeof ( DECOLOR_PARAM ) ) ;
if ( !*pDecolorParam )
return NO_ENOUGH_MEMORY ;
(*pDecolorParam) -> COE_Cr = ( int * )AMMemAlloc( MNull, (256+8)*2*sizeof ( int ) ) ;
(*pDecolorParam) -> COE_Cb = ( int * )AMMemAlloc( MNull, (256+8)*2*sizeof ( int ) ) ;
if ( !(*pDecolorParam) ->COE_Cr || !(*pDecolorParam) ->COE_Cb )
return NO_ENOUGH_MEMORY ;
for ( i = 0 ; i< 256 + 8 ; i++ ) {
(*pDecolorParam) -> COE_Cr[2*i] = (int)( 1.402 * (float)i - 50.956 ) ;
(*pDecolorParam) -> COE_Cr[2*i+1] = (int)( 176.976 - 0.71414 * (float)i ) ;
(*pDecolorParam) -> COE_Cb[2*i] = (int)( 1.772 * (float)i - 98.316 ) ;
(*pDecolorParam) -> COE_Cb[2*i+1] = (int)( 85.024 - 0.34414 * (float)i ) ;
}
#ifdef __WIN32__
(*pDecolorParam) -> OutWidth = lWidth ;
(*pDecolorParam) -> BackBytes = lWidth*3 + BitsRoundTo4Bytes(lWidth*24) ;
#endif
return READ_JPEG_OK ;
}
int callbackInfoInit(JPG_CALLBACK_PARAM **pCallbackParam, JPEG_HANDLE *hJpeg, int lWidth, int lHeight, MLong lUserParam ) {
int mcuResampleHigh = ( hJpeg->pInfo->HighSamp[0] * 8 * lHeight + hJpeg->pInfo->Height - 1) / hJpeg->pInfo->Height ;
*pCallbackParam = ( JPG_CALLBACK_PARAM * )AMMemAlloc( MNull, sizeof ( JPG_CALLBACK_PARAM ) ) ;
if ( !*pCallbackParam )
return NO_ENOUGH_MEMORY ;
(*pCallbackParam)->colorBits = hJpeg->pInfo->colorBits ;
(*pCallbackParam)->lUserParam = lUserParam ;
(*pCallbackParam)->lStatus = JPG_CALLBACK_INIT ;
(*pCallbackParam)->lLineBytes = (MLong)( lWidth * 3 ) ;
(*pCallbackParam)->lOutWidth = lWidth ;
(*pCallbackParam)->lOutHeight = lHeight ;
(*pCallbackParam)->nextBufferSize = mcuResampleHigh * 3 * lWidth ;
return READ_JPEG_OK ;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -