青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

coreBugZJ

此 blog 已棄。

數字圖像處理上機之一:BMP圖像文件讀寫和圖像顯示

 

實驗目的:
1. 了解BMP圖像文件格式;
2. 了解圖像顯示的方法;

實驗內容:
1. 用MFC構建圖像顯示和操作的界面;
2. 掌握圖像顯示的方法并實現它;
3. 編寫讀入BMP圖像文件的程序;
4. 編寫把圖像寫入BMP圖像文件的程序。

實驗環境:
1. 機器:PC機
2. OS:WindowsXP Professional +SP2
3. 開發平臺:MS Visual Studio 2005+SP1
4. 編程語言:C\C++\VC++



幾張截圖:










我的代碼是從之前的工作中剪裁拼接,加以修改而成,對于這一次實驗來說,代碼有些冗余。

*********************************************************

/*
ClassImageZ.h

Copyright (C) 2011, coreBugZJ, all rights reserved.

定義 ImageZ ,標準圖像類,所有算法都在此圖像上進行。
*/


#ifndef  __CLASSIMAGE_Z_H_INCLUDED__
#define  __CLASSIMAGE_Z_H_INCLUDED__


/*
ImageZ 圖像數據格式(參見 FormatImageZ.h):

真彩色圖像:
        像素數據:FORMAT_COLOR_B8G8R8A8_Z

調色板圖像:
        調色板數據:FORMAT_COLOR_B8G8R8A8_Z
        像素數據:FORMAT_INDEX_I8_Z
*/


#include "TypeZ.h"
#include "FormatImageZ.h"


/* ImageZ 圖像數據格式中的一些常數,使用這些常數來訪問圖像數據 */

        /* ImageZ 圖像數據格式中 顏色的格式 */
#define  IMAGEZ_FORMAT_COLOR_Z    FORMAT_COLOR_B8G8R8A8_Z

        /* ImageZ 圖像數據格式中 顏色索引的格式 */
#define  IMAGEZ_FORMAT_INDEX_Z    FORMAT_INDEX_I8_Z

        /* ImageZ 圖像數據格式中 顏色的大小,單位 字節 */
#define  IMAGEZ_COLOR_SIZE_Z      4

        /* ImageZ 圖像數據格式中 顏色中各分量的偏移,單位 字節 */
#define  IMAGEZ_OFFSET_BLUE_Z     0
#define  IMAGEZ_OFFSET_GREEN_Z    1
#define  IMAGEZ_OFFSET_RED_Z      2
#define  IMAGEZ_OFFSET_ALPHA_Z    3

        /* ImageZ 圖像數據格式中 索引的大小,單位 字節 */
#define  IMAGEZ_INDEX_SIZE_Z      1


        /* 圖像信息頭 */
struct _ImageInfoZ
{
        U32 width, height; /* 圖像寬高,單位 像素 */
        U32 linePitch;     /* 對齊后的寬度,用于定位像素,單位 字節 */
        U08 *pPixel;       /* 像素數據,需要對齊 */

        U32 colorNum;      /* 調色板顏色數量,== 0 真彩色圖像,> 0 調色板圖像。判斷是否真彩的唯一指標 */
        U08 *pPalette;     /* 調色板數據,無需對齊,== NULL 真彩色圖像 */
};
typedef  struct _ImageInfoZ  ImageInfoZ;

typedef        ImageInfoZ*   ImageZ;
typedef  const ImageInfoZ*  cImageZ;


        /* 判斷 ImageZ 數據結構是否合法 */
PublicFuncZ  B32  isImageValidZ( cImageZ img );
        /* 創建新圖像 */
        /* 失敗返回 NULL */
PublicFuncZ  ImageZ  createImageZ( U32 width, U32 height, U32 colorNum );
        /* 創建相同圖像,只是不復制圖像調色板數據和像素數據 */
        /* 失敗返回 NULL */
PublicFuncZ  ImageZ  createImageFromImageInfoZ( cImageZ src );
        /* 復制圖像 */
        /* 失敗返回 NULL */
PublicFuncZ  ImageZ  createImageFromImageZ( cImageZ src );
        /* 銷毀圖像 */
PublicFuncZ  R32  destroyImageZ( ImageZ img );
        /* 判斷點是否在圖像內 */
PublicFuncZ  B32  isInImageZ( cImageZ img, U32 x, U32 y );
        /* 寬高 */
PublicFuncZ  U32  getImageWidthZ( cImageZ img );
PublicFuncZ  U32  getImageHeightZ( cImageZ img );
PublicFuncZ  U32  getImageLinePitchZ( cImageZ img );
        /* 像素 顏色 */
PublicFuncZ  R32  getImageColorZ( cImageZ img, U32 x, U32 y, ColorZ *pColor );
PublicFuncZ  R32  putImageColorZ( ImageZ img, U32 x, U32 y, const ColorZ *pColor );
        /* 像素 調色板索引,只對調色板圖像有效 */
PublicFuncZ  R32  getImageIndexZ( cImageZ img, U32 x, U32 y, U08 *pIndex );
PublicFuncZ  R32  putImageIndexZ( cImageZ img, U32 x, U32 y, U08 index );
        /* 像素 根據圖像格式判斷是顏色還是調色板索引 */
PublicFuncZ  R32  getImagePixelZ( cImageZ img, U32 x, U32 y, PixelZ *pPixel );
PublicFuncZ  R32  putImagePixelZ( cImageZ img, U32 x, U32 y, const PixelZ *pPixel );
        /* 調色板 */
PublicFuncZ  B32  isImagePaletteUsedZ( cImageZ img );
PublicFuncZ  U32  getImageColorNumZ( cImageZ img );
        /* 獲取調色板中某顏色 */
PublicFuncZ  R32  getImagePaletteColorZ( cImageZ img, U08 index, ColorZ *pColor );
        /* 設置調色板中某顏色 */
PublicFuncZ  R32  putImagePaletteColorZ( ImageZ img, U08 index, const ColorZ *pColor );
        /* 調色板顏色數量相同,則復制調色板;都無調色板,也算執行成功 */
PublicFuncZ  R32  copyImagePaletteZ( ImageZ dest, cImageZ src );
        /* 交換圖像數據 */
PublicFuncZ  R32  swapImageZ( ImageZ imgA, ImageZ imgB );


#endif /* __CLASSIMAGE_Z_H_INCLUDED__ */

*********************************************************

/*
ClassImageZ.c

Copyright (C) 2011, coreBugZJ, all rights reserved.

定義 ImageZ ,標準圖像類,所有算法都在此圖像上進行。
*/


#include "stdafx.h"
#include "ClassImageZ.h"

#include <malloc.h>
#include <string.h>


PublicFuncZ  B32  isImageValidZ( cImageZ img ) {
        return (  (NULL != img) &&
                  (0 < img->width) && (0 < img->height) &&
                  (NULL != img->pPixel) &&
                  (  (  (0 == img->colorNum) &&
                        (NULL == img->pPalette) &&
                        (getFormatLinePitchZ(img->width, IMAGEZ_FORMAT_COLOR_Z) == img->linePitch)
                     ) ||
                     (  (0x2 <= img->colorNum) &&  (0x100 >= img->colorNum) &&
                        (NULL != img->pPalette) &&
                        (getFormatLinePitchZ(img->width, IMAGEZ_FORMAT_INDEX_Z) == img->linePitch)
                     )
                  )
               );
}

PublicFuncZ  ImageZ  createImageZ( U32 width, U32 height, U32 colorNum ) {
        ImageZ img;

        if ( (0 >= width) || (0 >= height) || (0x100 < colorNum) || (0x1 == colorNum) ) {
                return NULL;
        }

        img = (ImageZ)malloc( sizeof(ImageInfoZ) );
        if ( NULL == img ) {
                return NULL;
        }

        img->width     = width;
        img->height    = height;
        img->linePitch = getFormatLinePitchZ( img->width, ((0 == colorNum) ? IMAGEZ_FORMAT_COLOR_Z : IMAGEZ_FORMAT_INDEX_Z) );
        img->pPixel    = (U08*)malloc( img->linePitch * img->height );
        if ( NULL == img->pPixel ) {
                free( img );
                return NULL;
        }

        img->colorNum  = colorNum;
        img->pPalette  = NULL;
        if ( 0 < colorNum ) {
                img->pPalette = (U08*)malloc( IMAGEZ_COLOR_SIZE_Z * img->colorNum );
                if ( NULL == img->pPalette ) {
                        free( img->pPixel );
                        free( img );
                        return NULL;
                }
        }
        return img;
}

PublicFuncZ  ImageZ  createImageFromImageInfoZ( cImageZ src ) {
        if ( !isImageValidZ(src) ) {
                return NULL;
        }
        return createImageZ( src->width, src->height, src->colorNum );
}

PublicFuncZ  ImageZ  createImageFromImageZ( cImageZ src ) {
        ImageZ img = createImageFromImageInfoZ( src );
        if ( NULL == img ) {
                return NULL;
        }
        if ( 0 < img->colorNum ) {
                memcpy( img->pPalette, src->pPalette, IMAGEZ_COLOR_SIZE_Z * img->colorNum );
        }
        memcpy( img->pPixel, src->pPixel, img->linePitch * img->height );
        return img;
}

PublicFuncZ  R32  destroyImageZ( ImageZ img ) {
        if ( !isImageValidZ(img) ) {
                return RERR;
        }
        if ( NULL != img->pPalette ) {
                free( img->pPalette );
        }
        free( img->pPixel );
        free( img );
        return ROK;
}

PublicFuncZ  B32  isInImageZ( cImageZ img, U32 x, U32 y ) {
        return ( isImageValidZ(img) && (x < img->width) && (y < img->height) );
}

PublicFuncZ  U32  getImageWidthZ( cImageZ img ) {
        return ( isImageValidZ(img) ? img->width : 0 );
}

PublicFuncZ  U32  getImageHeightZ( cImageZ img ) {
        return ( isImageValidZ(img) ? img->height : 0 );
}

PublicFuncZ  U32  getImageLinePitchZ( cImageZ img ) {
        return ( isImageValidZ(img) ? img->linePitch : 0 );
}

PublicFuncZ  R32  getImageColorZ( cImageZ img, U32 x, U32 y, ColorZ *pColor ) {
        U08 *p;
        if ( isInImageZ(img, x, y) && (NULL != pColor) ) {
                if ( 0 == img->colorNum ) {
                        p = img->pPixel + y * img->linePitch + x * IMAGEZ_COLOR_SIZE_Z;
                }
                else {
                        p = img->pPalette + IMAGEZ_COLOR_SIZE_Z * ((img->pPixel)[ y * img->linePitch + x * IMAGEZ_INDEX_SIZE_Z

]);
                }
                pColor->b = p[ IMAGEZ_OFFSET_BLUE_Z  ];
                pColor->g = p[ IMAGEZ_OFFSET_GREEN_Z ];
                pColor->r = p[ IMAGEZ_OFFSET_RED_Z   ];
                pColor->a = p[ IMAGEZ_OFFSET_ALPHA_Z ];
                return ROK;
        }
        return RERR;
}

PublicFuncZ  R32  putImageColorZ( ImageZ img, U32 x, U32 y, const ColorZ *pColor ) {
        U08 *p;
        if ( isInImageZ(img, x, y) && (NULL != pColor) ) {
                if ( 0 == img->colorNum ) {
                        p = img->pPixel + y * img->linePitch + x * IMAGEZ_COLOR_SIZE_Z;
                        p[ IMAGEZ_OFFSET_BLUE_Z  ] = pColor->b;
                        p[ IMAGEZ_OFFSET_GREEN_Z ] = pColor->g;
                        p[ IMAGEZ_OFFSET_RED_Z   ] = pColor->r;
                        p[ IMAGEZ_OFFSET_ALPHA_Z ] = pColor->a;
                }
                else {
                        /* 不支持調色板圖像 */
                        return RERR;
                }
                return ROK;
        }
        return RERR;
}

PublicFuncZ  R32  getImageIndexZ( cImageZ img, U32 x, U32 y, U08 *pIndex ) {
        if ( isInImageZ(img, x, y) && (NULL != pIndex) && (0 < img->colorNum) ) {
                *pIndex = (img->pPixel)[ y * img->linePitch + x ];
                return ROK;
        }
        return RERR;
}

PublicFuncZ  R32  putImageIndexZ( cImageZ img, U32 x, U32 y, U08 index ) {
        if ( isInImageZ(img, x, y) && (index < img->colorNum) ) {
                (img->pPixel)[ y * img->linePitch + x ] = index;
                return ROK;
        }
        return RERR;
}

PublicFuncZ  R32  getImagePixelZ( cImageZ img, U32 x, U32 y, PixelZ *pPixel ) {
        U08 *p;
        if ( isInImageZ(img, x, y) && (NULL != pPixel) ) {
                if ( 0 == img->colorNum ) {
                        p = img->pPixel + y * img->linePitch + x * IMAGEZ_COLOR_SIZE_Z;
                        pPixel->color.b = p[ IMAGEZ_OFFSET_BLUE_Z  ];
                        pPixel->color.g = p[ IMAGEZ_OFFSET_GREEN_Z ];
                        pPixel->color.r = p[ IMAGEZ_OFFSET_RED_Z   ];
                        pPixel->color.a = p[ IMAGEZ_OFFSET_ALPHA_Z ];
                }
                else {
                        p = img->pPixel + y * img->linePitch + x * IMAGEZ_INDEX_SIZE_Z;
                        pPixel->index = p[ 0 ];
                }
                return ROK;
        }
        return RERR;
}

PublicFuncZ  R32  putImagePixelZ( cImageZ img, U32 x, U32 y, const PixelZ *pPixel ) {
        U08 *p;
        if ( isInImageZ(img, x, y) && (NULL != pPixel) ) {
                if ( 0 == img->colorNum ) {
                        p = img->pPixel + y * img->linePitch + x * IMAGEZ_COLOR_SIZE_Z;
                        p[ IMAGEZ_OFFSET_BLUE_Z  ] = pPixel->color.b;
                        p[ IMAGEZ_OFFSET_GREEN_Z ] = pPixel->color.g;
                        p[ IMAGEZ_OFFSET_RED_Z   ] = pPixel->color.r;
                        p[ IMAGEZ_OFFSET_ALPHA_Z ] = pPixel->color.a;
                }
                else {
                        p = img->pPixel + y * img->linePitch + x * IMAGEZ_INDEX_SIZE_Z;
                        p[ 0 ] = pPixel->index;
                }
                return ROK;
        }
        return RERR;
}

PublicFuncZ  B32  isImagePaletteUsedZ( cImageZ img ) {
        return ( isImageValidZ(img) && (0 < img->colorNum) );
}

PublicFuncZ  U32  getImageColorNumZ( cImageZ img ) {
        return ( isImageValidZ(img) ? img->colorNum : 0 );
}

PublicFuncZ  R32  getImagePaletteColorZ( cImageZ img, U08 index, ColorZ *pColor ) {
        U08 *p;
        if ( isImageValidZ(img) && (index < img->colorNum) && (NULL != pColor) ) {
                p = img->pPalette + IMAGEZ_COLOR_SIZE_Z * index;
                pColor->b = p[ IMAGEZ_OFFSET_BLUE_Z  ];
                pColor->g = p[ IMAGEZ_OFFSET_GREEN_Z ];
                pColor->r = p[ IMAGEZ_OFFSET_RED_Z   ];
                pColor->a = p[ IMAGEZ_OFFSET_ALPHA_Z ];
                return ROK;
        }
        return RERR;
}

PublicFuncZ  R32  putImagePaletteColorZ( ImageZ img, U08 index, const ColorZ *pColor ) {
        U08 *p;
        if ( isImageValidZ(img) && (index < img->colorNum) && (NULL != pColor) ) {
                p = img->pPalette + IMAGEZ_COLOR_SIZE_Z * index;
                p[ IMAGEZ_OFFSET_BLUE_Z  ] = pColor->b;
                p[ IMAGEZ_OFFSET_GREEN_Z ] = pColor->g;
                p[ IMAGEZ_OFFSET_RED_Z   ] = pColor->r;
                p[ IMAGEZ_OFFSET_ALPHA_Z ] = pColor->a;
                return ROK;
        }
        return RERR;
}

PublicFuncZ  R32  copyImagePaletteZ( ImageZ dest, cImageZ src ) {
        if ( isImageValidZ(dest) && isImageValidZ(src) && (dest->colorNum == src->colorNum) ) {
                if ( 0 < src->colorNum ) {
                        memcpy( dest->pPalette, src->pPalette, IMAGEZ_COLOR_SIZE_Z * src->colorNum );
                }
                return ROK;
        }
        return RERR;
}

PublicFuncZ  R32  swapImageZ( ImageZ imgA, ImageZ imgB ) {
        U08 *p;
        U32 u;

        if ( (!isImageValidZ(imgA)) || (!isImageValidZ(imgB)) ) {
                return RERR;
        }

#define  SW(a,b,t)   t = a; a = b; b = t

        SW( imgA->width,     imgB->width,     u );
        SW( imgA->height,    imgB->height,    u );
        SW( imgA->linePitch, imgB->linePitch, u );
        SW( imgA->pPixel,    imgB->pPixel,    p );

        SW( imgA->colorNum, imgB->colorNum, u );
        SW( imgA->pPalette, imgB->pPalette, p );

#undef SW

        return ROK;
}

*********************************************************

/*
ClassStreamZ.h

Copyright (C) 2011, coreBugZJ, all rights reserved.

定義 StreamZ ,數據流類。封裝對 文件 或 內存 的處理。
*/


#ifndef  __CLASSSTREAM_Z_H_INCLUDED__
#define  __CLASSSTREAM_Z_H_INCLUDED__


#include "TypeZ.h"

#include <stdio.h>


/* 使用模式 */
        /* 讀文件 */
#define  STREAM_MODE_FILE_IN_Z     0x01
        /* 寫文件 */
#define  STREAM_MODE_FILE_OUT_Z    0x02
        /* 讀內存 */
#define  STREAM_MODE_MEMORY_IN_Z   0x03
        /* 寫內存 */
#define  STREAM_MODE_MEMORY_OUT_Z  0x04


struct _StreamInfoZ
{
        U32  mode;     /* 使用模式 */
        FILE *file;    /* 關聯的文件 */
        U08  *memory;  /* 關聯的內存 或 讀寫文件的緩存 */
        U32  memSize;  /* memory 所占內存大小 */
        U32  memEnd;   /* memory 中的實際數據的邊界 */
        U32  memPos;   /* 當前在 memory 中的讀寫位置 */
};
typedef  struct _StreamInfoZ  StreamInfoZ;

typedef        StreamInfoZ *   StreamZ;
typedef  const StreamInfoZ *  cStreamZ;


        /* 判斷 StreamZ 數據結構是否合法 */
PublicFuncZ  B32  isStreamValidZ( cStreamZ srm );
        /* 新建流,并與文件關聯 */
        /* 失敗返回 NULL */
PublicFuncZ  StreamZ  createStreamFromFileZ( cSz08 fileName, U32 modeFile );
        /* 新建流,并與內存關聯 */
        /* 失敗返回 NULL */
PublicFuncZ  StreamZ  createStreamFromMemoryZ( U08 *memory, U32 memSize, U32 modeMemory );
        /* 銷毀流,并釋放資源 */
PublicFuncZ  R32  destroyStreamZ( StreamZ srm );

        /* 輸入 */
PublicFuncZ  R32  getStreamU08Z( StreamZ srm, U08 *pU );
PublicFuncZ  R32  getStreamU08ArrayZ( StreamZ srm, U08 *arr, U32 len );
        /* Lbf 低位字節先,Mbf 高位字節先 */
PublicFuncZ  R32  getStreamU16LbfZ( StreamZ srm, U16 *pU );
PublicFuncZ  R32  getStreamU16MbfZ( StreamZ srm, U16 *pU );
PublicFuncZ  R32  getStreamU32LbfZ( StreamZ srm, U32 *pU );
PublicFuncZ  R32  getStreamU32MbfZ( StreamZ srm, U32 *pU );
PublicFuncZ  R32  getStreamI32LbfZ( StreamZ srm, I32 *pI );
PublicFuncZ  R32  getStreamI32MbfZ( StreamZ srm, I32 *pI );
        /* 跳過若干字節 */
PublicFuncZ  R32  getStreamSkipZ( StreamZ srm, U32 n );

        /* 輸出 */
PublicFuncZ  R32  putStreamU08Z( StreamZ srm, U08 u );
PublicFuncZ  R32  putStreamU08ArrayZ( StreamZ srm, const U08 *arr, U32 len );
        /* Lbf 低位字節先,Mbf 高位字節先 */
PublicFuncZ  R32  putStreamU16LbfZ( StreamZ srm, U16 u );
PublicFuncZ  R32  putStreamU16MbfZ( StreamZ srm, U16 u );
PublicFuncZ  R32  putStreamU32LbfZ( StreamZ srm, U32 u );
PublicFuncZ  R32  putStreamU32MbfZ( StreamZ srm, U32 u );
PublicFuncZ  R32  putStreamI32LbfZ( StreamZ srm, I32 i );
PublicFuncZ  R32  putStreamI32MbfZ( StreamZ srm, I32 i );
        /* 將寫文件緩存清空,緩存數據寫入文件,只對寫文件模式有效 */
PublicFuncZ  R32  putStreamFlushZ( StreamZ srm );


#endif /* __CLASSSTREAM_Z_H_INCLUDED__ */

*********************************************************

/*
ClassStreamZ.c

Copyright (C) 2011, coreBugZJ, all rights reserved.

定義 StreamZ ,數據流類。封裝對 文件 或 內存 的處理。
未使用位運算。
*/


#include "stdafx.h"
#include "ClassStreamZ.h"

#include <malloc.h>
#include <string.h>


/* 讀寫文件時,緩存大小 */
#define STREAM_BUFFER_SIZE_Z   1024


PublicFuncZ  B32  isStreamValidZ( cStreamZ srm ) {
        if ( NULL == srm ) {
                return FALSE;
        }
        switch ( srm->mode ) {
        case STREAM_MODE_FILE_IN_Z :
        case STREAM_MODE_FILE_OUT_Z :
                return ( (NULL != srm->file) && (NULL != srm->memory) &&
                         (STREAM_BUFFER_SIZE_Z == srm->memSize) &&
                         (srm->memPos <= srm->memEnd) && (srm->memEnd <= srm->memSize)
                       );
        case STREAM_MODE_MEMORY_IN_Z :
        case STREAM_MODE_MEMORY_OUT_Z :
                return ( (NULL == srm->file) && (NULL != srm->memory) &&
                         (0 < srm->memSize) &&
                         (srm->memPos <= srm->memEnd) && (srm->memEnd <= srm->memSize)
                       );
        }
        return FALSE;
}

PublicFuncZ  StreamZ  createStreamFromFileZ( cSz08 fileName, U32 modeFile ) {
        StreamZ srm = (StreamZ)malloc( sizeof(StreamInfoZ) );
        if ( NULL == srm ) {
                return NULL;
        }

        srm->file = NULL;
        switch ( modeFile ) {
        case STREAM_MODE_FILE_IN_Z :
                srm->file = fopen( fileName, "rb" );
                break;
        case STREAM_MODE_FILE_OUT_Z :
                srm->file = fopen( fileName, "wb" );
                break;
        }

        if ( NULL == srm->file ) {
                free( srm );
                return NULL;
        }
        srm->mode   = modeFile;
        srm->memory = (U08*)malloc( STREAM_BUFFER_SIZE_Z );
        if ( NULL == srm->memory ) {
                fclose( srm->file );
                free( srm );
                return NULL;
        }
        srm->memSize = STREAM_BUFFER_SIZE_Z;
        srm->memPos  = 0;
        srm->memEnd  = 0;

        return srm;
}

PublicFuncZ  StreamZ  createStreamFromMemoryZ( U08 *memory, U32 memSize, U32 modeMemory ) {
        StreamZ srm;

        if ( (NULL == memory) || (0 >= memSize) ||
             ((STREAM_MODE_MEMORY_IN_Z != modeMemory) && (STREAM_MODE_MEMORY_OUT_Z != modeMemory))
           ) {
                return NULL;
        }

        srm = (StreamZ)malloc( sizeof(StreamInfoZ) );
        if ( NULL == srm ) {
                return NULL;
        }
        srm->mode    = modeMemory;
        srm->file    = NULL;
        srm->memory  = memory;
        srm->memSize = memSize;
        srm->memPos  = 0;
        srm->memEnd  = ((STREAM_MODE_MEMORY_IN_Z == srm->mode) ? memSize : 0 );

        return srm;
}

PublicFuncZ  R32  destroyStreamZ( StreamZ srm ) {
        if ( !isStreamValidZ(srm) ) {
                return RERR;
        }

        switch ( srm->mode ) {
        case STREAM_MODE_FILE_OUT_Z :
                putStreamFlushZ( srm );
        case STREAM_MODE_FILE_IN_Z :
                fclose( srm->file );
                free( srm->memory );
                break;
        case STREAM_MODE_MEMORY_IN_Z :
        case STREAM_MODE_MEMORY_OUT_Z :
                break;
        default :
                return RERR;
        }

        free( srm );
        return ROK;
}

/****************************************************************************************/

PublicFuncZ  R32  getStreamU08Z( StreamZ srm, U08 *pU ) {
        return getStreamU08ArrayZ( srm, pU, 1 );
}

PublicFuncZ  R32  getStreamU08ArrayZ( StreamZ srm, U08 *arr, U32 len ) {
        U32 i = 0, t;
        if ( (!isStreamValidZ(srm)) || (NULL == arr) || (0 >= len) ||
             ((STREAM_MODE_FILE_IN_Z != srm->mode) && (STREAM_MODE_MEMORY_IN_Z != srm->mode))
           ) {
                return RERR;
        }
        while ( i < len ) {
                if ( srm->memPos >= srm->memEnd ) {
                        if ( STREAM_MODE_FILE_IN_Z != srm->mode ) {
                                return RERR;
                        }
                        srm->memEnd = fread( srm->memory, 1, srm->memSize, srm->file );
                        srm->memPos = 0;
                        if ( 0 >= srm->memEnd ) {
                                return RERR;
                        }
                }
                t = (((len - i) < (srm->memEnd - srm->memPos)) ? (len - i) : (srm->memEnd - srm->memPos));
                memcpy( arr + i, srm->memory + srm->memPos, t );
                i += t;
                srm->memPos += t;
        }
        return ROK;
}

PublicFuncZ  R32  getStreamU16LbfZ( StreamZ srm, U16 *pU ) {
        if ( ROK != getStreamU08ArrayZ( srm, (U08*)pU, 2 ) ) {
                return RERR;
        }
        *pU = (U16)( ((U16)0x100) * (((U08*)pU)[1]) + (((U08*)pU)[0]) );
        return ROK;
}

PublicFuncZ  R32  getStreamU16MbfZ( StreamZ srm, U16 *pU ) {
        if ( ROK != getStreamU08ArrayZ( srm, (U08*)pU, 2 ) ) {
                return RERR;
        }
        *pU = (U16)( ((U16)0x100) * (((U08*)pU)[0]) + (((U08*)pU)[1]) );
        return ROK;
}

PublicFuncZ  R32  getStreamU32LbfZ( StreamZ srm, U32 *pU ) {
        if ( ROK != getStreamU08ArrayZ( srm, (U08*)pU, 4 ) ) {
                return RERR;
        }
        *pU = (U32)( ((U32)0x1000000) * (((U08*)pU)[3]) +
                     ((U32)0x10000  ) * (((U08*)pU)[2]) +
                     ((U32)0x100    ) * (((U08*)pU)[1]) +
                     (((U08*)pU)[0])  );
        return ROK;
}

PublicFuncZ  R32  getStreamU32MbfZ( StreamZ srm, U32 *pU ) {
        if ( ROK != getStreamU08ArrayZ( srm, (U08*)pU, 4 ) ) {
                return RERR;
        }
        *pU = (U32)( ((U32)0x1000000) * (((U08*)pU)[0]) +
                     ((U32)0x10000  ) * (((U08*)pU)[1]) +
                     ((U32)0x100    ) * (((U08*)pU)[2]) +
                     (((U08*)pU)[3])  );
        return ROK;
}

PublicFuncZ  R32  getStreamI32LbfZ( StreamZ srm, I32 *pI ) {
        return getStreamU32LbfZ( srm, (U32*)pI );
}

PublicFuncZ  R32  getStreamI32MbfZ( StreamZ srm, I32 *pI ) {
        return getStreamU32MbfZ( srm, (U32*)pI );
}

PublicFuncZ  R32  getStreamSkipZ( StreamZ srm, U32 n ) {
        if ( (!isStreamValidZ(srm)) ||  (0 >= n) ||
             ((STREAM_MODE_FILE_IN_Z != srm->mode) && (STREAM_MODE_MEMORY_IN_Z != srm->mode))
           ) {
                return RERR;
        }
        if ( srm->memPos + n <= srm->memEnd ) {
                srm->memPos += n;
                return ROK;
        }
        n -= srm->memEnd - srm->memPos;
        srm->memPos = 0;
        srm->memEnd = 0;
        if ( (STREAM_MODE_FILE_IN_Z != srm->mode) ||
             (0 != fseek( srm->file, n, SEEK_CUR ))
           ) {
                return RERR;
        }
        return ROK;
}

/****************************************************************************************/

PublicFuncZ  R32  putStreamU08Z( StreamZ srm, U08 u ) {
        return putStreamU08ArrayZ( srm, &u, 1 );
}

PublicFuncZ  R32  putStreamU08ArrayZ( StreamZ srm, const U08 *arr, U32 len ) {
        U32 i = 0, t;
        if ( (!isStreamValidZ(srm)) || (NULL == arr) || (0 >= len) ||
             ((STREAM_MODE_FILE_OUT_Z != srm->mode) && (STREAM_MODE_MEMORY_OUT_Z != srm->mode))
           ) {
                return RERR;
        }
        while ( i < len ) {
                if ( srm->memPos >= srm->memSize ) {
                        if ( (STREAM_MODE_FILE_OUT_Z != srm->mode) ||
                             (fwrite( srm->memory, 1, srm->memSize, srm->file ) != srm->memSize)
                           ){
                                return RERR;
                        }
                        srm->memPos = 0;
                        srm->memEnd = 0;
                }
                t = (((len - i) < (srm->memSize - srm->memPos)) ? (len - i) : (srm->memSize - srm->memPos));
                memcpy( srm->memory + srm->memPos, arr + i, t );
                i += t;
                srm->memPos += t;
                srm->memEnd  = srm->memPos;
        }
        return ROK;
}

PublicFuncZ  R32  putStreamU16LbfZ( StreamZ srm, U16 u ) {
        U08 b[ 2 ];
        b[ 0 ] = (U08)( u % 0x100 );
        b[ 1 ] = (U08)( u / 0x100 );
        return putStreamU08ArrayZ( srm, b, 2 );
}

PublicFuncZ  R32  putStreamU16MbfZ( StreamZ srm, U16 u ) {
        U08 b[ 2 ];
        b[ 1 ] = (U08)( u % 0x100 );
        b[ 0 ] = (U08)( u / 0x100 );
        return putStreamU08ArrayZ( srm, b, 2 );
}

PublicFuncZ  R32  putStreamU32LbfZ( StreamZ srm, U32 u ) {
        U08 b[ 4 ];
        b[ 0 ] = (U08)( u % 0x100 );
        u /= 0x100;
        b[ 1 ] = (U08)( u % 0x100 );
        u /= 0x100;
        b[ 2 ] = (U08)( u % 0x100 );
        b[ 3 ] = (U08)( u / 0x100 );
        return putStreamU08ArrayZ( srm, b, 4 );
}

PublicFuncZ  R32  putStreamU32MbfZ( StreamZ srm, U32 u ) {
        U08 b[ 4 ];
        b[ 3 ] = (U08)( u % 0x100 );
        u /= 0x100;
        b[ 2 ] = (U08)( u % 0x100 );
        u /= 0x100;
        b[ 1 ] = (U08)( u % 0x100 );
        b[ 0 ] = (U08)( u / 0x100 );
        return putStreamU08ArrayZ( srm, b, 4 );
}

PublicFuncZ  R32  putStreamI32LbfZ( StreamZ srm, I32 i ) {
        return putStreamU32LbfZ( srm, (U32)i );
}

PublicFuncZ  R32  putStreamI32MbfZ( StreamZ srm, I32 i ) {
        return putStreamU32MbfZ( srm, (U32)i );
}

PublicFuncZ  R32  putStreamFlushZ( StreamZ srm ) {
        if ( (!isStreamValidZ(srm)) || (STREAM_MODE_FILE_OUT_Z != srm->mode) ) {
                return RERR;
        }
        if ( srm->memPos > 0 ) {
                if ( fwrite( srm->memory, 1, srm->memPos, srm->file ) != srm->memPos ) {
                        return RERR;
                }
                srm->memPos = 0;
                srm->memEnd = 0;
        }
        return ROK;
}

*********************************************************

/*
DisplayWin32Z.h

Copyright (C) 2011, coreBugZJ, all rights reserved.

Win32 平臺下函數聲明。
*/


#ifndef  __DISPLAYWIN32_Z_H_INCLUDED__
#define  __DISPLAYWIN32_Z_H_INCLUDED__


#include "TypeZ.h"
#include "ClassImageZ.h"

#include <Windows.h>


        /* 無縮放將圖像某區域顯示在 DC 中指定位置 */
PublicFuncZ  R32 displayImageZ( HDC hdcDest, I32 leftDest, I32 topDest,
                U32 width, U32 height,
                cImageZ imgSrc, U32 leftSrc, U32 topSrc );

 

#endif /* __DISPLAYWIN32_Z_H_INCLUDED__ */

*********************************************************

/*
DisplayWin32Z.c

Copyright (C) 2011, coreBugZJ, all rights reserved.

平臺相關但接口一致函數定義,Win32 平臺下函數定義。
*/


#include "stdafx.h"
#include "DisplayZ.h"

#include <malloc.h>
#include <string.h>


/* 平臺相關但接口一致函數定義 ============================= */

/* def */


/* Win32 平臺下函數定義 =================================== */

PublicFuncZ  R32 displayImageZ( HDC hdcDest, I32 leftDest, I32 topDest,
                U32 width, U32 height,
                cImageZ imgSrc, U32 leftSrc, U32 topSrc ) {
        /* 將真彩色圖像轉化為 32 位位圖,將調色板圖像轉化為 8 位位圖,再顯示。*/
        /* 依賴 ImageZ 圖像數據格式 與 windows 位圖格式的匹配 */
        BITMAPINFO *pinfo;
        U32 imgWidth, imgHeight, linePitch;
        B32 colorNum, hasPal;

        if ( !isImageValidZ(imgSrc) ) {
                return RERR;
        }

        imgWidth  = getImageWidthZ( imgSrc );
        linePitch = getImageLinePitchZ( imgSrc );
        imgHeight = getImageHeightZ( imgSrc );
        hasPal    = isImagePaletteUsedZ( imgSrc );
        colorNum  = getImageColorNumZ( imgSrc );

        if ( (width < 1) || (height < 1) ||
             (leftSrc >= imgWidth) || (topSrc >= imgHeight)
           ) {
                return ROK;
        }
        if ( leftSrc + width > imgWidth ) {
                width = imgWidth - leftSrc;
        }
        if ( topSrc + height > imgHeight ) {
                height = imgHeight - topSrc;
        }

        pinfo = (BITMAPINFO*)malloc( sizeof(BITMAPINFOHEADER) + colorNum * 4 + 16 );
        if ( NULL == pinfo ) {
                return RERR;
        }

        pinfo->bmiHeader.biBitCount  = ( hasPal ? 8 : 32  );
        pinfo->bmiHeader.biClrImportant = 0;
        pinfo->bmiHeader.biClrUsed   = ( hasPal ? colorNum : 0  );
        pinfo->bmiHeader.biCompression = BI_RGB;
        pinfo->bmiHeader.biHeight    = 0 - imgHeight;
        pinfo->bmiHeader.biPlanes    = 1;
        pinfo->bmiHeader.biSize      = sizeof(BITMAPINFOHEADER);
        pinfo->bmiHeader.biSizeImage = linePitch * imgHeight;
        pinfo->bmiHeader.biWidth     = imgWidth;
        pinfo->bmiHeader.biXPelsPerMeter = 0;
        pinfo->bmiHeader.biYPelsPerMeter = 0;

        if ( hasPal ) {
                memcpy( ((U08*)pinfo) + sizeof(BITMAPINFOHEADER), imgSrc->pPalette, IMAGEZ_COLOR_SIZE_Z * colorNum );
        }

        SetDIBitsToDevice( hdcDest, leftDest, topDest,
                width, height,
                leftSrc, topSrc,
                0, imgHeight,
                (void*)(imgSrc->pPixel),
                pinfo,
                DIB_RGB_COLORS );

        free( pinfo );
        return ROK;
}

*********************************************************

/*
DisplayZ.h

Copyright (C) 2011, coreBugZJ, all rights reserved.

顯示圖像(依平臺劃分模塊)(平臺無關函數聲明,平臺相關但接口一致函數聲明,包含平臺相關文件)。
*/


#ifndef  __DISPLAY_Z_H_INCLUDED__
#define  __DISPLAY_Z_H_INCLUDED__


/* #include "" */


/* 平臺無關函數聲明 ==================================== */

/* decl */


/* 平臺相關但接口一致函數聲明 ========================== */

/* decl */


/* 包含平臺相關文件 ==================================== */

#include "DisplayWin32Z.h"


#endif /* __DISPLAY_Z_H_INCLUDED__ */

*********************************************************

/*
FormatBmpZ.h

Copyright (C) 2011, coreBugZJ, all rights reserved.

BMP 文件格式常量。
*/


#ifndef  __FORMATBMP_Z_H_INCLUDED__
#define  __FORMATBMP_Z_H_INCLUDED__


/* BMP 文件頭大小 */
#define  BMP_FILEHEADER_SIZE_Z    0x0E


/* BMP 文件壓縮方案 */
        /* 不壓縮 */
#define  BMP_CODE_RGB_Z   0


/* BMP 信息頭大小 */
#define  BMP_COREHEADER_SIZE_Z    0x0C
#define  BMP_INFOHEADER_SIZE_Z    0x28
#define  BMP_V4HEADER_SIZE_Z      0x6C
#define  BMP_V5HEADER_SIZE_Z      0x7C


#endif /* __FORMATBMP_Z_H_INCLUDED__ */

*********************************************************

/*
FormatImageZ.h

Copyright (C) 2011, coreBugZJ, all rights reserved.

圖像數據格式(非圖像文件格式) 及 相關工具。
*/


#ifndef  __FORMATIMAGE_Z_H_INCLUDED__
#define  __FORMATIMAGE_Z_H_INCLUDED__


#include "TypeZ.h"


/* 顏色格式(調色板圖像的調色板數據,真彩色圖像的像素數據) */
        /* 32 位真彩色,內存低地址到高地址依次為 BlueGreenRedAlpha,各 8 位 */
#define  FORMAT_COLOR_B8G8R8A8_Z   100
        /* 24 位 */
#define  FORMAT_COLOR_B8G8R8_Z     110


/* 調色板索引格式(調色板圖像的像素數據) */
        /* 8 位調色板,內存為 8 位調色板索引 */
#define  FORMAT_INDEX_I8_Z         10
        /* 4 位 */
#define  FORMAT_INDEX_I4_Z         20
        /* 1 位 */
#define  FORMAT_INDEX_I1_Z         30


        /* 判斷格式是否合法 */
PublicFuncZ  B32  isFormatValidZ( U32 colorNum, U32 fmtPalette, U32 fmtPixel );
        /* 判斷像素數據格式是否合法 */
PublicFuncZ  B32  isPixelFormatValidZ( U32 fmtPixel );
        /* 判斷調色板數據格式是否合法 */
PublicFuncZ  B32  isPaletteFormatValidZ( U32 fmtPalette );
        /* 獲取顏色大小,單位 字節,失敗返回 0 */
PublicFuncZ  U32  getFormatColorSizeZ( U32 fmtColor );
        /* 轉換顏色格式 */
PublicFuncZ  R32  convertFormatColorZ( U32 fmtDest, U08 *pColorDest, U32 fmtSrc, U08 *pColorSrc );
        /* 由像素寬度,計算 4 字節對齊后的字節寬度,失敗返回 0 */
PublicFuncZ  U32  getFormatLinePitchZ( U32 width, U32 fmtPixel );


#endif /* __FORMATIMAGE_Z_H_INCLUDED__ */

*********************************************************

/*
FormatImageZ.c

Copyright (C) 2011, coreBugZJ, all rights reserved.

圖像數據格式(非圖像文件格式) 及 相關工具。
*/


#include "stdafx.h"
#include "FormatImageZ.h"


PublicFuncZ  B32  isFormatValidZ( U32 colorNum, U32 fmtPalette, U32 fmtPixel ) {
        switch ( fmtPixel ) {
        case FORMAT_COLOR_B8G8R8A8_Z :
        case FORMAT_COLOR_B8G8R8_Z :
                return (0x0 == colorNum);
        case FORMAT_INDEX_I8_Z :
                return ( (0x2 <= colorNum) && (0x100 >= colorNum) && (isPaletteFormatValidZ(fmtPalette)) );
        case FORMAT_INDEX_I4_Z :
                return ( (0x2 <= colorNum) && (0x10  >= colorNum) && (isPaletteFormatValidZ(fmtPalette)) );
        case FORMAT_INDEX_I1_Z :
                return ( (0x2 == colorNum) && (isPaletteFormatValidZ(fmtPalette)) );
        }
        return FALSE;
}

PublicFuncZ  B32  isPixelFormatValidZ( U32 fmtPixel ) {
        switch ( fmtPixel ) {
        case FORMAT_COLOR_B8G8R8A8_Z :
        case FORMAT_COLOR_B8G8R8_Z :
        case FORMAT_INDEX_I8_Z :
        case FORMAT_INDEX_I4_Z :
        case FORMAT_INDEX_I1_Z :
                return TRUE;
        }
        return FALSE;
}

PublicFuncZ  B32  isPaletteFormatValidZ( U32 fmtPalette ) {
        switch ( fmtPalette ) {
        case FORMAT_COLOR_B8G8R8A8_Z :
        case FORMAT_COLOR_B8G8R8_Z :
                return TRUE;
        }
        return FALSE;
}

PublicFuncZ  U32  getFormatColorSizeZ( U32 fmtColor ) {
        switch ( fmtColor ) {
        case FORMAT_COLOR_B8G8R8A8_Z :
                return 4;
        case FORMAT_COLOR_B8G8R8_Z :
                return 3;
        }
        return 0;
}

PublicFuncZ  R32  convertFormatColorZ( U32 fmtDest, U08 *pColorDest, U32 fmtSrc, U08 *pColorSrc ) {
        U08 color[ 8 ];
        switch ( fmtSrc ) {
        case FORMAT_COLOR_B8G8R8A8_Z :
                color[ 0 ] = pColorSrc[ 0 ];
                color[ 1 ] = pColorSrc[ 1 ];
                color[ 2 ] = pColorSrc[ 2 ];
                color[ 3 ] = pColorSrc[ 3 ];
                break;
        case FORMAT_COLOR_B8G8R8_Z :
                color[ 0 ] = pColorSrc[ 0 ];
                color[ 1 ] = pColorSrc[ 1 ];
                color[ 2 ] = pColorSrc[ 2 ];
                color[ 3 ] = 0;
                break;
        default :
                return RERR;
        }
        switch ( fmtSrc ) {
        case FORMAT_COLOR_B8G8R8A8_Z :
                pColorDest[ 0 ] = color[ 0 ];
                pColorDest[ 1 ] = color[ 1 ];
                pColorDest[ 2 ] = color[ 2 ];
                pColorDest[ 3 ] = color[ 3 ];
                break;
        case FORMAT_COLOR_B8G8R8_Z :
                pColorDest[ 0 ] = color[ 0 ];
                pColorDest[ 1 ] = color[ 1 ];
                pColorDest[ 2 ] = color[ 2 ];
                break;
        default :
                return RERR;
        }
        return ROK;
}

PublicFuncZ  U32  getFormatLinePitchZ( U32 width, U32 fmtPixel ) {
        U32 bpp = 0;
        switch ( fmtPixel ) {
        case FORMAT_COLOR_B8G8R8A8_Z :
                bpp = 32;
                break;
        case FORMAT_COLOR_B8G8R8_Z :
                bpp = 24;
                break;
        case FORMAT_INDEX_I8_Z :
                bpp = 8;
                break;
        case FORMAT_INDEX_I4_Z :
                bpp = 4;
                break;
        case FORMAT_INDEX_I1_Z :
                bpp = 1;
                break;
        default :
                return 0;
        }
        return ( ( ( ( ( width * bpp ) + 7 ) / 8 ) + 3 ) / 4 ) * 4;
}

*********************************************************

/*
FormatZ.h

Copyright (C) 2011, coreBugZJ, all rights reserved.

圖像格式。
*/


#ifndef  __FORMAT_Z_H_INCLUDED__
#define  __FORMAT_Z_H_INCLUDED__


/* ImageZ */
#include "FormatImageZ.h"


/* BMP */
#define  FORMAT_BMP_CORE_Z     10
#define  FORMAT_BMP_INFO_Z     20
#define  FORMAT_BMP_V4_Z       30
#define  FORMAT_BMP_V5_Z       40
#include "FormatBmpZ.h"


#define  FORMAT_BMP_Z          FORMAT_BMP_INFO_Z


#endif /* __FORMAT_Z_H_INCLUDED__ */

*********************************************************

/*
ImageZ.h

Copyright (C) 2011, coreBugZJ, all rights reserved.

圖形庫 ImageZ 的總頭文件,使用圖形庫(直接使用源碼 或 使用動態鏈接庫等)時包含此頭文件即可。
*/


#ifndef  __IMAGE_Z_H_INCLUDED__
#define  __IMAGE_Z_H_INCLUDED__


#include "TypeZ.h"
#include "TypeFileInfoZ.h"
#include "ClassImageZ.h"
#include "ClassStreamZ.h"
#include "FormatZ.h"
#include "InputZ.h"
#include "DisplayZ.h"
#include "OutputZ.h"


#endif /* __IMAGE_Z_H_INCLUDED__ */

*********************************************************

/*
InputZ.h

Copyright (C) 2011, coreBugZJ, all rights reserved.

讀入圖像。
*/


#ifndef  __INPUT_Z_H_INCLUDED__
#define  __INPUT_Z_H_INCLUDED__


#include "TypeZ.h"
#include "ClassImageZ.h"
#include "ClassStreamZ.h"


PublicFuncZ  ImageZ  createImageFromStreamBmpZ( StreamZ srm );
PublicFuncZ  ImageZ  createImageFromFileBmpZ( cSz08 fileName );


#endif /* __INPUT_Z_H_INCLUDED__ */

*********************************************************

/*
InputZ.c

Copyright (C) 2011, coreBugZJ, all rights reserved.

讀入圖像。
*/


#include "stdafx.h"
#include "InputZ.h"
#include "FormatBmpZ.h"
#include "FormatImageZ.h"

#include <malloc.h>


        /* 目前支持無壓縮的 1 位,4 位,8 位,24 位,32 位 的位圖 */
        /* 認為 32 位位圖不使用 Alpha */
PublicFuncZ  ImageZ  createImageFromStreamBmpZ( StreamZ srm ) {
        ImageZ   img = NULL;  /* 圖像 */

        U08 bfType0, bfType1; /* BMP 文件類型標識 */
        U32 bfOffBits;        /* 像素數據在文件中的偏移 */

        /* FORMAT_BMP_INFO_Z, FORMAT_BMP_V4_Z, FORMAT_BMP_V5_Z 統一處理 */
        U32 hdrSize;          /* 圖像信息頭大小,識別不同版本 BMP 文件 */

        U32 bpp, code;        /* 每像素數據位數,壓縮方案 */
        U32 width, height;    /* 圖像寬高,單位 像素 */
        U32 linePitch;        /* 4 字節對齊后的欲讀文件中圖像寬度,單位 字節 */
        U32 imgLinePitch;     /* 4 字節對齊后的 ImageZ 圖像寬度,單位字節 */

        /* 過濾與圖像數據無關的調色板 */
        U32 hdrColor;         /* 真彩色圖像的調色板顏色數 */

        /* 不同格式調色板統一處理 */
        U32 colorNum;         /* 調色板顏色數量 */
        U32 palColorSize;     /* 調色板中每個顏色大小,單位 字節 */

        U32 i;                /* 讀入調色板,像素數據 循環變量 */
        U32 x, y;             /* 讀入像素數據 循環變量 */
        U08 *p;               /* 讀入調色板,像素數據 臨時變量 */

        /* 讀入調色板數據,一行圖像數據 緩存 */
        U32 bufLen;           /* 緩存 大小 */
        U08 *buf = NULL;

        /* 24 位,32 位 未壓縮圖像 統一處理 */
        U32 pixelSize;        /* 像素大小,單位 字節 */

        /* 8 位,4 位,1 位 未壓縮圖像 統一處理 */
        U32 indexMod;         /* 從字節中分離出調色板索引 */
        U32 pixelPerByte;     /* 每字節像素數量 */

        /* 自頂向下,自底向上 統一處理 */
        B32 topDown;          /* 是否自頂向下 */
        I32 step;             /* 讀入像素時的行增量,單位 字節 */
        U08 *pPixel;          /* 讀入像素時,每行的起始 */

        /* 2 的 n 次方,不使用位運算 */
        U32 n2n[] = { 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048 };

#define  EXIT_ERR  do { destroyImageZ( img ); free( buf ); return NULL; } while ( 0 )

        if ( !isStreamValidZ(srm) ) {
                return NULL;
        }

        if ( (ROK != getStreamU08Z( srm, &bfType0 )) ||
             (ROK != getStreamU08Z( srm, &bfType1 )) ||
             ('B' != bfType0) || ('M' != bfType1) ||
             (ROK != getStreamSkipZ( srm, 8 )) ||
             (ROK != getStreamU32LbfZ( srm, &bfOffBits )) ||
             (ROK != getStreamU32LbfZ( srm, &hdrSize ))
           ) EXIT_ERR;

        switch ( hdrSize ) {
        case BMP_V5HEADER_SIZE_Z :
                /* FORMAT_BMP_INFO_Z, FORMAT_BMP_V4_Z, FORMAT_BMP_V5_Z 統一處理 */
        case BMP_V4HEADER_SIZE_Z :
                /* FORMAT_BMP_INFO_Z, FORMAT_BMP_V4_Z, FORMAT_BMP_V5_Z 統一處理 */
        case BMP_INFOHEADER_SIZE_Z :
                /* FORMAT_BMP_INFO_Z, FORMAT_BMP_V4_Z, FORMAT_BMP_V5_Z 統一處理 */

                /* FORMAT_BMP_INFO_Z */
                {
                I32 biWidth, biHeight;
                U16 biBitCount;
                U32 biCompression, biClrUsed;

                if ( (ROK != getStreamI32LbfZ( srm, &biWidth  )) ||
                     (ROK != getStreamI32LbfZ( srm, &biHeight )) ||
                     (biWidth < 1) || (biHeight == 0) ||
                     (ROK != getStreamSkipZ( srm, 2 )) ||
                     (ROK != getStreamU16LbfZ( srm, &biBitCount )) ||
                     (ROK != getStreamU32LbfZ( srm, &biCompression )) ||
                     (ROK != getStreamSkipZ( srm, 12 )) ||
                     (ROK != getStreamU32LbfZ( srm, &biClrUsed )) ||
                     (ROK != getStreamSkipZ( srm, 4 + hdrSize - BMP_INFOHEADER_SIZE_Z ))
                   ) EXIT_ERR;

                bpp      = biBitCount;
                code     = biCompression;
                topDown  = ( biHeight < 0 );
                width    = biWidth;
                height   = ( topDown ? (-biHeight) : biHeight );
                colorNum = ( (bpp > 8) ? 0 : ( (biClrUsed == 0) ? n2n[bpp] : biClrUsed ) );
                palColorSize = 4;
                hdrColor     = biClrUsed;

                if (!(  (  ( (bpp ==  1) || (bpp ==  4) ||
                             (bpp ==  8) || (bpp == 24) ||
                             (bpp == 32)
                           ) &&
                           (code == BMP_CODE_RGB_Z)
                        ) /* ||
                        ( (bpp == 16) && (code == )
                        ) */
                     )
                   ) EXIT_ERR;

                } /* FORMAT_BMP_INFO_Z */

                break;

        case BMP_COREHEADER_SIZE_Z :
                /* FORMAT_BMP_CORE_Z */
                {
                U16 bcWidth, bcHeight, bcBitCount;

                if ( (ROK != getStreamU16LbfZ( srm, &bcWidth )) ||
                     (ROK != getStreamU16LbfZ( srm, &bcHeight )) ||
                     (bcWidth < 1) || (bcHeight < 1) ||
                     (ROK != getStreamSkipZ( srm, 2 )) ||
                     (ROK != getStreamU16LbfZ( srm, &bcBitCount ))
                   ) EXIT_ERR;

                bpp      = bcBitCount;
                code     = BMP_CODE_RGB_Z;
                topDown  = FALSE;
                width    = bcWidth;
                height   = bcHeight;
                colorNum = ( (bpp > 8) ? 0 : n2n[bpp] );
                palColorSize = 3;
                hdrColor     = 0;

                if (!(  (bpp == 1) || (bpp ==  4) ||
                        (bpp == 8) || (bpp == 24)
                     )
                   ) EXIT_ERR;

                } /* FORMAT_BMP_CORE_Z */

                break;

        default :
                EXIT_ERR;
        }

        /* 真彩色圖像使用調色板優化基于調色板的顯示設備的顯示效果,這里忽略之 */
        if ( (0 == colorNum) && (0 < hdrColor) ) {
                if ( ROK != getStreamSkipZ( srm, hdrColor * palColorSize ) )
                        EXIT_ERR;
        }

        img  = createImageZ( width, height, colorNum );
        if ( !isImageValidZ(img) )
                EXIT_ERR;

        pixelPerByte = 8 / bpp;
        pixelSize = bpp / 8;
        indexMod  = ( (bpp <= 8) ? n2n[bpp] : 0 );
        linePitch = ( ( ( width * bpp + 7 ) / 8 + 3 ) / 4 ) * 4;
        imgLinePitch = img->linePitch;
        step      = ( topDown ? imgLinePitch : (0-imgLinePitch) );
        pPixel    = img->pPixel + ( topDown ? 0 : (height * imgLinePitch - imgLinePitch) );
        bufLen    = 16 + ( (colorNum * palColorSize < linePitch) ? linePitch : (colorNum * palColorSize) );
        buf  = (U08*)malloc( bufLen );
        if ( NULL == buf )
                EXIT_ERR;

        /* 不同格式調色板 統一處理 */
        if ( 0 < colorNum ) {
                if ( ROK != getStreamU08ArrayZ( srm, buf, colorNum * palColorSize ) )
                        EXIT_ERR;
                for ( i = 0; i < colorNum; ++i ) {
                        p = img->pPalette + i * IMAGEZ_COLOR_SIZE_Z;
                        p[ IMAGEZ_OFFSET_BLUE_Z  ] = buf[ i * palColorSize + 0 ];
                        p[ IMAGEZ_OFFSET_GREEN_Z ] = buf[ i * palColorSize + 1 ];
                        p[ IMAGEZ_OFFSET_RED_Z   ] = buf[ i * palColorSize + 2 ];
                        p[ IMAGEZ_OFFSET_ALPHA_Z ] = 255;
                }
        }

        switch ( bpp ) {
        case 32 :
                /* 未壓縮的 32 位位圖,未壓縮的 24 位位圖 統一處理 */
        case 24 :
                /* 未壓縮的 32 位位圖,未壓縮的 24 位位圖 統一處理 */
                if ( code == BMP_CODE_RGB_Z ) {
                        for ( y = 0; y < height; ++y ) {
                                if ( ROK != getStreamU08ArrayZ( srm, buf, linePitch ) ) {
                                        EXIT_ERR;
                                }
                                for ( x = 0; x < width; ++x ) {
                                        p = pPixel + x * IMAGEZ_COLOR_SIZE_Z;
                                        p[ IMAGEZ_OFFSET_BLUE_Z  ] = buf[ x * pixelSize + 0 ];
                                        p[ IMAGEZ_OFFSET_GREEN_Z ] = buf[ x * pixelSize + 1 ];
                                        p[ IMAGEZ_OFFSET_RED_Z   ] = buf[ x * pixelSize + 2 ];
                                        p[ IMAGEZ_OFFSET_ALPHA_Z ] = 255;
                                }
                                pPixel += step;
                        }
                }
                else {
                        EXIT_ERR;
                }
                break;

        case 16 :
                EXIT_ERR;
                break;

        case  8 :
                /* 未壓縮的 8 位位圖,未壓縮的 4 位位圖,未壓縮的 1 位位圖 統一處理 */
        case  4 :
                /* 未壓縮的 8 位位圖,未壓縮的 4 位位圖,未壓縮的 1 位位圖 統一處理 */
        case  1 :
                /* 未壓縮的 8 位位圖,未壓縮的 4 位位圖,未壓縮的 1 位位圖 統一處理 */
                if ( code == BMP_CODE_RGB_Z ) {
                        for ( y = 0; y < height; ++y ) {
                                if ( ROK != getStreamU08ArrayZ( srm, buf, linePitch ) )
                                        EXIT_ERR;
                                i = 0;
                                for ( x = 0; x < width; ++x ) {
                                        p = pPixel + x * IMAGEZ_INDEX_SIZE_Z;
                                        *p = ( buf[x/pixelPerByte] / n2n[8-bpp-i*bpp] ) % indexMod;
                                        if ( (*p) >= colorNum )
                                                EXIT_ERR;
                                        ++i;
                                        if ( i >= pixelPerByte ) {
                                                i = 0;
                                        }
                                }
                                pPixel += step;
                        }
                }
                else {
                        EXIT_ERR;
                }
                break;

        default :
                EXIT_ERR;
        }

        free( buf );
        return img;
#undef  EXIT_ERR
}

PublicFuncZ  ImageZ  createImageFromFileBmpZ( cSz08 fileName ) {
        ImageZ  img;
        StreamZ srm = createStreamFromFileZ( fileName, STREAM_MODE_FILE_IN_Z );
        if ( !isStreamValidZ(srm) ) {
                return NULL;
        }
        img = createImageFromStreamBmpZ( srm );
        destroyStreamZ( srm );
        if ( !isImageValidZ(img) ) {
                return NULL;
        }
        return img;
}

*********************************************************

/*
OutputZ.h

Copyright (C) 2011, coreBugZJ, all rights reserved.

保存圖像。
*/


#ifndef  __OUTPUT_Z_H_INCLUDED__
#define  __OUTPUT_Z_H_INCLUDED__


#include "TypeZ.h"
#include "TypeFileInfoZ.h"
#include "ClassImageZ.h"
#include "ClassStreamZ.h"


PublicFuncZ  R32  saveImageToStreamZ( cImageZ img, StreamZ srm, cPtrFileInfoZ pfi );
PublicFuncZ  R32  saveImageToFileZ( cImageZ img, cSz08 fileName, cPtrFileInfoZ pfi );
        /* 計算圖像保存后的文件大小,單位 字節;失敗返回 0 */
PublicFuncZ  U32  getImageFileSizeZ( cImageZ img, cPtrFileInfoZ pfi );


#endif /* __OUTPUT_Z_H_INCLUDED__ */

*********************************************************

/*
OutputZ.c

Copyright (C) 2011, coreBugZJ, all rights reserved.

保存圖像。
*/


#include "stdafx.h"
#include "OutputZ.h"
#include "FormatZ.h"


PrivateFuncZ  R32  saveImageToStreamBmpZ( cImageZ img, StreamZ srm, cPtrFileInfoZ pfi );


PublicFuncZ  R32  saveImageToStreamZ( cImageZ img, StreamZ srm, cPtrFileInfoZ pfi ) {
        if ( !isFileInfoValidZ(pfi) ) {
                return RERR;
        }
        switch ( pfi->fmt ) {
        case FORMAT_BMP_Z :
                return saveImageToStreamBmpZ( img, srm, pfi );
        }
        return RERR;
}

PublicFuncZ  R32  saveImageToFileZ( cImageZ img, cSz08 fileName, cPtrFileInfoZ pfi ) {
        R32 res;
        StreamZ srm = createStreamFromFileZ( fileName, STREAM_MODE_FILE_OUT_Z );
        if ( NULL == srm ) {
                return RERR;
        }
        res = saveImageToStreamZ( img, srm, pfi );
        destroyStreamZ( srm );
        return res;
}

PublicFuncZ  U32  getImageFileSizeZ( cImageZ img, cPtrFileInfoZ pfi ) {
        if ( (!isImageValidZ(img)) || (!isFileInfoValidZ(pfi)) ) {
                return 0;
        }

        switch ( pfi->fmt ) {
        case FORMAT_BMP_Z :
                return getImageLinePitchZ(img) * getImageHeightZ(img) +
                       getImageColorNumZ(img) * IMAGEZ_COLOR_SIZE_Z +
                       BMP_FILEHEADER_SIZE_Z + BMP_INFOHEADER_SIZE_Z;
        }
        return 0;
}


PrivateFuncZ  R32  saveImageToStreamBmpZ( cImageZ img, StreamZ srm, cPtrFileInfoZ pfi ) {
        U32 width;       /* 圖像寬,單位 像素 */
        I32 iwidth;      /* 圖像寬,考慮方向,單位 像素 */
        U32 linePitch;   /* 圖像寬,對齊后,單位 字節 */
        U32 height;      /* 圖像高,單位 像素 */
        I32 iheight;     /* 圖像高,考慮方向,單位 像素 */
        U32 colorNum;    /* 調色板顏色數 */
        U32 offbits;     /* 圖像像素數據在文件中的偏移,單位 字節 */
        U32 imgSize;     /* 圖像像素數據量,單位 字節 */
        U32 fileSize;    /* 文件大小,單位 字節 */

        if ( (!isImageValidZ(img)) || (!isStreamValidZ(srm)) ||
             (!isFileInfoValidZ(pfi)) || (FORMAT_BMP_Z != pfi->fmt)
           ) {
                return RERR;
        }

        width     = getImageWidthZ( img );
        iwidth    = width;
        linePitch = getImageLinePitchZ( img );
        height    = getImageHeightZ( img );
        iheight   = 0 - height;
        colorNum  = getImageColorNumZ(img);
        offbits   = colorNum * IMAGEZ_COLOR_SIZE_Z + BMP_FILEHEADER_SIZE_Z + BMP_INFOHEADER_SIZE_Z;
        imgSize   = linePitch * height;
        fileSize  = offbits + imgSize;

        /* FILEHEADER */
        if ( (ROK != putStreamU08Z(srm, (U08)('B'))) ||
             (ROK != putStreamU08Z(srm, (U08)('M'))) ||
             (ROK != putStreamU32LbfZ(srm, fileSize)) ||
             (ROK != putStreamU32LbfZ(srm, 0)) ||
             (ROK != putStreamU32LbfZ(srm, offbits))
           ) {
                   return RERR;
        }

        /* INFOHEADER */
        if ( (ROK != putStreamU32LbfZ(srm, BMP_INFOHEADER_SIZE_Z)) ||
             (ROK != putStreamI32LbfZ(srm, iwidth)) ||
             (ROK != putStreamI32LbfZ(srm, iheight)) ||
             (ROK != putStreamU16LbfZ(srm, 1)) ||
             (ROK != putStreamU16LbfZ(srm, ((0==colorNum)?32:8))) ||
             (ROK != putStreamU32LbfZ(srm, BMP_CODE_RGB_Z)) ||
             (ROK != putStreamU32LbfZ(srm, imgSize)) ||
             (ROK != putStreamI32LbfZ(srm, 0)) ||
             (ROK != putStreamI32LbfZ(srm, 0)) ||
             (ROK != putStreamU32LbfZ(srm, colorNum)) ||
             (ROK != putStreamU32LbfZ(srm, 0))
           ) {
                     return RERR;
        }

        /* PALETTE */
        if ( 0 < colorNum ) {
                if ( ROK != putStreamU08ArrayZ(srm, img->pPalette, colorNum*IMAGEZ_COLOR_SIZE_Z) ) {
                        return RERR;
                }
        }

        /* PIXEL */
        if ( ROK != putStreamU08ArrayZ(srm, img->pPixel, imgSize) ) {
                return RERR;
        }

        return ROK;
}

*********************************************************

/*
TypeFileInfoZ.h

Copyright (C) 2011, coreBugZJ, all rights reserved.

定義 FileInfoZ ,圖像文件信息(如 圖像格式,jpeg屬性,BMP 位深度 等)。
*/


#ifndef  __TYPEFILEINFO_Z_H_INCLUDED__
#define  __TYPEFILEINFO_Z_H_INCLUDED__


#include "TypeZ.h"


struct _FileInfoZ
{
        U32 fmt;  /* 文件格式,FORMAT_BMP_Z ... */

        struct /* BMP 文件 */
        {
                U32 subfmt; /* 子格式,FORMAT_BMP_INFO_Z, FORMAT_BMP_CORE_Z ... */
                U32 bpp;    /* 每像素位數,1,4,8,16,24,32 */
                U32 code;   /* 編碼方案 */
        } bmp;
};
typedef  struct _FileInfoZ  FileInfoZ;
typedef  FileInfoZ  *PtrFileInfoZ;
typedef  const FileInfoZ  *cPtrFileInfoZ;


PublicFuncZ  B32  isFileInfoValidZ( cPtrFileInfoZ pfi );


#endif /* __TYPEFILEINFO_Z_H_INCLUDED__ */

*********************************************************

/*
TypeFileInfoZ.c

Copyright (C) 2011, coreBugZJ, all rights reserved.

定義 FileInfoZ ,圖像文件信息(如 圖像格式,jpeg屬性,BMP 位深度 等)。
*/


#include "stdafx.h"
#include "TypeFileInfoZ.h"
#include "FormatZ.h"


PublicFuncZ  B32  isFileInfoValidZ( cPtrFileInfoZ pfi ) {
        if ( NULL == pfi ) {
                return FALSE;
        }
        switch ( pfi->fmt ) {
        case FORMAT_BMP_Z :
                return ( (BMP_CODE_RGB_Z == pfi->bmp.code) &&
                         ( (FORMAT_BMP_INFO_Z == pfi->bmp.subfmt) ||
                           (FORMAT_BMP_CORE_Z == pfi->bmp.subfmt) ||
                           (FORMAT_BMP_V4_Z == pfi->bmp.subfmt) ||
                           (FORMAT_BMP_V5_Z == pfi->bmp.subfmt)
                         ) &&
                         ( (32==pfi->bmp.bpp) || (24==pfi->bmp.bpp) ||
                           /* (16==pfi->bmp.bpp) || */
                           (8==pfi->bmp.bpp)||(4==pfi->bmp.bpp)||(1==pfi->bmp.bpp)
                         )
                       );
        }
        return FALSE;
}

*********************************************************

/*
TypeZ.h

Copyright (C) 2011, coreBugZJ, all rights reserved.

定義無需構造析構的數據類型及部分常量,宏。
*/


#ifndef  __TYPE_Z_H_INCLUDED__
#define  __TYPE_Z_H_INCLUDED__


/* 帶符號整數 */
typedef  char   I08;
typedef  short  I16;
typedef  int    I32;


/* 無符號整數 */
typedef  unsigned char   U08;
typedef  unsigned short  U16;
typedef  unsigned int    U32;


/* 函數返回狀態類型和常量 */
typedef  U32   R32;
#define  ROK   10
#define  RERR  20


/* 布爾類型和常量 */
typedef  U32   B32;
#ifndef  TRUE
#define  TRUE  1
#endif
#ifndef  FALSE
#define  FALSE 0
#endif


/* ANSI 字符和字符串 */
typedef  char  C08;
typedef  C08*  Sz08;
typedef  const C08 * cSz08;


/* NULL */
#ifndef  NULL
#ifdef  __cplusplus
#define  NULL  0
#else
#define  NULL  ((void*)0)
#endif
#endif


/* 顏色 */
struct _ColorZ
{
        U08 b, g, r, a;
};
typedef  struct _ColorZ  ColorZ;


/* 像素 */
union _PixelZ
{
        ColorZ color;
        U08    index;
};
typedef  union _PixelZ  PixelZ;


/* 函數 */
#define  PrivateFuncZ  static
#define  PublicFuncZ


#endif /* __TYPE_Z_H_INCLUDED__ */

*********************************************************

// ImageADoc.cpp : implementation of the CImageADoc class
//

#include "stdafx.h"
#include "ImageA.h"

#include "ImageADoc.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// CImageADoc

IMPLEMENT_DYNCREATE(CImageADoc, CDocument)

BEGIN_MESSAGE_MAP(CImageADoc, CDocument)
END_MESSAGE_MAP()


// CImageADoc construction/destruction

CImageADoc::CImageADoc()
{
 // TODO: add one-time construction code here
        /* coreBugZJ */
        this->image = NULL;
}

CImageADoc::~CImageADoc()
{
}

BOOL CImageADoc::OnNewDocument()
{
 if (!CDocument::OnNewDocument())
  return FALSE;

 // TODO: add reinitialization code here
 // (SDI documents will reuse this document)

 return TRUE;
}

 


// CImageADoc serialization

void CImageADoc::Serialize(CArchive& ar)
{
 if (ar.IsStoring())
 {
                /* coreBugZJ */
                FileInfoZ fi;
                U32 len;
                U08 *buffer;
                StreamZ srm;

                fi.fmt = FORMAT_BMP_Z;
                fi.bmp.subfmt = FORMAT_BMP_INFO_Z;
                fi.bmp.code = BMP_CODE_RGB_Z;
                fi.bmp.bpp  = 32;

                len = getImageFileSizeZ( this->image, &fi );
                buffer = (U08*)malloc( len );
                if ( NULL != buffer ) {
                        srm = createStreamFromMemoryZ( buffer, len, STREAM_MODE_MEMORY_OUT_Z );
                        if ( NULL != srm ) {
                                if ( ROK != saveImageToStreamZ( this->image, srm, &fi ) ) {
                                        ::AfxMessageBox( TEXT("save Failed") );
                                }
                                else {
                                        ar.Write( buffer, len );
                                }
                                destroyStreamZ( srm );
                        }
                        free( buffer );
                }
 }
 else
 {
                /* coreBugZJ */
                destroyImageZ( this->image );
                this->image = NULL;

                U32 len = (U32)(ar.GetFile()->GetLength());
                U08 *buffer = (U08*)malloc( len );
                if ( NULL != buffer ) {
                        if ( ar.Read( buffer, len ) == len ) {
                                StreamZ srm = createStreamFromMemoryZ( buffer, len, STREAM_MODE_MEMORY_IN_Z );
                                if ( NULL != srm ) {
                                        this->image = createImageFromStreamBmpZ( srm );
                                        destroyStreamZ(srm );
                                }
                        }
                        free( buffer );
                }
        }
}


// CImageADoc diagnostics

#ifdef _DEBUG
void CImageADoc::AssertValid() const
{
 CDocument::AssertValid();
}

void CImageADoc::Dump(CDumpContext& dc) const
{
 CDocument::Dump(dc);
}
#endif //_DEBUG


// CImageADoc commands

*********************************************************

void CImageAView::OnDraw(CDC* pDC)
{
 CImageADoc* pDoc = GetDocument();
 ASSERT_VALID(pDoc);
 if (!pDoc)
  return;

 // TODO: add draw code for native data here
        /* coreBugZJ */
        displayImageZ( pDC->GetSafeHdc(), 0, 0,
                getImageWidthZ(pDoc->image), getImageHeightZ(pDoc->image),
                pDoc->image, 0, 0 );
}

*********************************************************

 

posted on 2011-09-22 22:00 coreBugZJ 閱讀(5426) 評論(3)  編輯 收藏 引用 所屬分類: VideoImage課內作業

Feedback

# re: 數字圖像處理上機之一:BMP圖像文件讀寫和圖像顯示 2011-09-23 19:35 cheap lace front wigs

好高深哦,學習了。。  回復  更多評論   

# re: 數字圖像處理上機之一:BMP圖像文件讀寫和圖像顯示[未登錄] 2014-12-11 19:39 Jack

@cheap lace front wigs

能不能給發分源代碼?。?多謝大神!  回復  更多評論   

# re: 數字圖像處理上機之一:BMP圖像文件讀寫和圖像顯示 2014-12-12 09:29 coreBugZJ

@Jack
幾年前學習圖像處理的時候試圖寫一個庫的,但沒設計好,且許多算法實現起來工作量太大且效果不如已有的庫好,所以現在做圖像處理還是使用的第三方庫。這些代碼我自己覺得寫得不好,你想要讀寫BMP的話,可以參考MSDN的資料、 CxImage、OpenCV等的讀寫BMP的代碼(我當時是這么做的)?,F在許多VC++圖像處理的書也都附有BMP讀寫代碼的,或者找找hdibapi.h/.c,cdib.h/.c之類的文件。  回復  更多評論   


青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            欧美视频中文在线看| 欧美国产另类| 国产一区二区久久| 久久久久五月天| 久久久久99精品国产片| 在线观看成人小视频| 欧美成人a视频| 欧美成人一区在线| 亚洲图片在线观看| 亚洲专区欧美专区| 狠狠色狠狠色综合系列| 国产精品va在线播放| 国产精品久久国产精品99gif| 亚洲性色视频| 香蕉久久夜色精品国产使用方法| 狠狠久久婷婷| 亚洲国产欧美一区二区三区同亚洲 | 国产在线视频欧美| 欧美成人小视频| 欧美日韩在线第一页| 欧美在线视频观看免费网站| 久久精品久久99精品久久| 在线观看一区视频| 亚洲视频中文字幕| 亚洲第一中文字幕| 亚洲一区二区三区色| 1000部国产精品成人观看| 日韩一级黄色片| 国产一区二区三区免费不卡| 亚洲国产日韩一级| 国产精品一二三四区| 亚洲国产清纯| 国产一区二区久久精品| 亚洲最新在线| 亚洲国产成人av在线| 亚洲一区二区不卡免费| 亚洲区国产区| 欧美专区在线| 午夜精品视频网站| 欧美福利视频在线| 久久资源在线| 国产毛片久久| 亚洲调教视频在线观看| 亚洲美女电影在线| 久久综合狠狠综合久久综合88| 午夜国产一区| 欧美视频一区二区三区四区| 欧美大尺度在线观看| 国产自产精品| 欧美一区二区免费| 欧美在线一级视频| 国产精品萝li| 亚洲午夜国产成人av电影男同| 日韩一区二区免费高清| 免费观看久久久4p| 欧美国产大片| 在线观看一区视频| 久久久久久一区| 卡通动漫国产精品| 国产亚洲综合精品| 欧美亚洲一区| 久久久www成人免费毛片麻豆| 国产精品久久久久毛片大屁完整版| 亚洲国产日日夜夜| 亚洲美女av在线播放| 欧美极品在线观看| 亚洲人成绝费网站色www| 亚洲精品麻豆| 欧美日韩国产成人| 一区二区成人精品| 午夜一区二区三区不卡视频| 国产精品日韩欧美大师| 亚洲一二三区在线观看| 这里只有视频精品| 91久久久久久久久久久久久| 久久久福利视频| 狂野欧美激情性xxxx| 影音先锋成人资源站| 久久免费视频观看| 亚洲第一在线综合网站| 亚洲精品一区二区三| 欧美区国产区| 亚洲图片在线观看| 久久精品91| 亚洲风情亚aⅴ在线发布| 欧美刺激午夜性久久久久久久| 亚洲日韩第九十九页| 一区二区三区www| 国产精品av一区二区| 亚洲欧美另类中文字幕| 美女诱惑一区| 夜久久久久久| 国产日韩欧美a| 久久夜色精品国产噜噜av| 亚洲欧洲另类国产综合| 午夜精品福利一区二区三区av| 国产日韩欧美制服另类| 久久久久久一区二区三区| 亚洲片国产一区一级在线观看| 亚洲免费在线电影| 亚洲成人直播| 欧美性色综合| 久久综合色8888| 亚洲一区二区精品视频| 美女视频黄a大片欧美| 在线亚洲免费视频| 亚洲大片免费看| 国产精品日韩久久久| 欧美va天堂| 欧美亚洲一区二区在线| 亚洲精品欧美日韩| 久久综合色8888| 午夜国产一区| 一区二区免费在线观看| 伊人精品成人久久综合软件| 欧美性开放视频| 欧美精品一区二区三区在线看午夜 | 亚洲精品极品| 国产日韩精品视频一区| 欧美日韩在线另类| 久久影音先锋| 欧美中文在线观看| 亚洲欧美另类国产| 99综合精品| 91久久久精品| 欧美国产第二页| 老司机午夜精品| 欧美在线日韩精品| 亚洲免费视频一区二区| 日韩一级网站| 亚洲精品欧洲精品| 亚洲国产婷婷综合在线精品 | 国产欧美一区二区三区久久| 欧美日韩国产成人在线91| 久久综合一区| 久久久久久网址| 久久久蜜臀国产一区二区| 亚洲欧美成人精品| 亚洲免费在线观看视频| 一区二区毛片| 亚洲午夜视频| 亚洲午夜精品国产| 久久综合久色欧美综合狠狠| 激情文学一区| 精品成人在线视频| 国产伊人精品| 黑人巨大精品欧美一区二区 | 欧美绝品在线观看成人午夜影视| 久久综合伊人77777| 久久婷婷国产综合国色天香| 久久久精品一区二区三区| 久久久久久久综合| 久久婷婷一区| 欧美精品一区二区三区在线播放| 欧美国产另类| 国产精品久久网| 国产日韩欧美视频| 亚洲春色另类小说| 亚洲国产一区二区视频| 亚洲精品系列| 亚洲自啪免费| 久久免费高清| 亚洲国产日韩欧美在线99| 亚洲每日更新| 亚洲欧美网站| 麻豆成人在线观看| 欧美日韩三区| 国内激情久久| 亚洲精品视频一区| 午夜激情亚洲| 欧美xxx在线观看| 夜夜爽99久久国产综合精品女不卡| 在线性视频日韩欧美| 久久精品99国产精品日本| 欧美成人精品高清在线播放| 欧美三区在线| 亚洲高清一区二| 亚洲一级片在线观看| 久久九九久精品国产免费直播 | 午夜久久福利| 麻豆视频一区二区| 一本久道久久久| 久久久在线视频| 欧美视频在线一区| 亚洲电影第三页| 久久se精品一区精品二区| 欧美激情亚洲综合一区| 亚洲一区成人| 欧美日本在线| 樱桃成人精品视频在线播放| 亚洲无线一线二线三线区别av| 久久免费午夜影院| 亚洲最新视频在线播放| 久久夜色精品国产欧美乱极品| 国产精品theporn| 亚洲人成小说网站色在线| 久久丁香综合五月国产三级网站| 亚洲黄色片网站| 久久久久久久综合色一本| 国产精品久久久久免费a∨ |