⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jpeg.c

📁 JPEG解压软件,包含PC端的测试程序,程序结构比较清晰
💻 C
📖 第 1 页 / 共 2 页
字号:
#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 + -