From d7de620182c56233ee0f273f37ca6e9ae3d28946 Mon Sep 17 00:00:00 2001 From: Viktor Szakats Date: Tue, 26 Jan 2010 16:27:27 +0000 Subject: [PATCH] 2010-01-26 17:26 UTC+0100 Viktor Szakats (harbour.01 syenar.hu) * contrib/hbwin/Makefile * contrib/hbwin/hbwin.h * contrib/hbwin/win_bmp.c + contrib/hbwin/win_bmpd.c * contrib/hbwin/win_tprn.prg + contrib/hbwin/win_tbmp.prg + Moved WIN_BMP() class to separate source file. + Moved WIN_BITMAPDIMENSIONS() and its low-level support functions to separate source file, to avoid creating unwanted dependency to libpng. + Applied Xavi's patches to WIN_BMP(). * Restored nError parameter for ::IsSupported() * ::LoadFile() now fills dimensions automatically. * ::Draw() 3rd dim array parameter replaced with nError. * contrib/hbwin/hbwapi.h + Added 'extern' keyword. --- harbour/ChangeLog | 19 ++ harbour/contrib/hbwin/Makefile | 4 +- harbour/contrib/hbwin/hbwapi.h | 34 +-- harbour/contrib/hbwin/hbwin.h | 12 ++ harbour/contrib/hbwin/win_bmp.c | 289 +------------------------ harbour/contrib/hbwin/win_bmpd.c | 329 +++++++++++++++++++++++++++++ harbour/contrib/hbwin/win_tbmp.prg | 122 +++++++++++ harbour/contrib/hbwin/win_tprn.prg | 71 ------- 8 files changed, 510 insertions(+), 370 deletions(-) create mode 100644 harbour/contrib/hbwin/win_bmpd.c create mode 100644 harbour/contrib/hbwin/win_tbmp.prg diff --git a/harbour/ChangeLog b/harbour/ChangeLog index 49b3b95789..c85e361c93 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -17,6 +17,25 @@ past entries belonging to author(s): Viktor Szakats. */ +2010-01-26 17:26 UTC+0100 Viktor Szakats (harbour.01 syenar.hu) + * contrib/hbwin/Makefile + * contrib/hbwin/hbwin.h + * contrib/hbwin/win_bmp.c + + contrib/hbwin/win_bmpd.c + * contrib/hbwin/win_tprn.prg + + contrib/hbwin/win_tbmp.prg + + Moved WIN_BMP() class to separate source file. + + Moved WIN_BITMAPDIMENSIONS() and its low-level support functions + to separate source file, to avoid creating unwanted + dependency to libpng. + + Applied Xavi's patches to WIN_BMP(). + * Restored nError parameter for ::IsSupported() + * ::LoadFile() now fills dimensions automatically. + * ::Draw() 3rd dim array parameter replaced with nError. + + * contrib/hbwin/hbwapi.h + + Added 'extern' keyword. + 2010-01-26 15:47 UTC+0100 Viktor Szakats (harbour.01 syenar.hu) * utils/hbmk2/hbmk2.prg + Added -hbexe option. This is the default, but it may help hbide diff --git a/harbour/contrib/hbwin/Makefile b/harbour/contrib/hbwin/Makefile index 1251ce4241..aa927bb34d 100644 --- a/harbour/contrib/hbwin/Makefile +++ b/harbour/contrib/hbwin/Makefile @@ -21,6 +21,7 @@ C_SOURCES := \ wce_simc.c \ wce_smsc.c \ win_bmp.c \ + win_bmpd.c \ win_com.c \ win_dlg.c \ win_dll.c \ @@ -45,9 +46,10 @@ PRG_SOURCES := \ oleauto.prg \ axfunc.prg \ wce_sim.prg \ - win_tcom.prg \ win_os.prg \ win_reg.prg \ + win_tbmp.prg \ + win_tcom.prg \ win_tprn.prg \ C_HEADERS := \ diff --git a/harbour/contrib/hbwin/hbwapi.h b/harbour/contrib/hbwin/hbwapi.h index 6266d50b67..34210f5b17 100644 --- a/harbour/contrib/hbwin/hbwapi.h +++ b/harbour/contrib/hbwin/hbwapi.h @@ -99,27 +99,27 @@ HB_EXTERN_BEGIN -HB_EXPORT void hbwapi_SetLastError( DWORD dwLastError ); -HB_EXPORT DWORD hbwapi_GetLastError( void ); +extern HB_EXPORT void hbwapi_SetLastError( DWORD dwLastError ); +extern HB_EXPORT DWORD hbwapi_GetLastError( void ); -HB_EXPORT POINT * hbwapi_par_POINT( POINT * p, int iParam, HB_BOOL bMandatory ); -HB_EXPORT RECT * hbwapi_par_RECT( RECT * p, int iParam, HB_BOOL bMandatory ); -HB_EXPORT DOCINFO * hbwapi_par_DOCINFO( DOCINFO * p, int iParam, HB_BOOL bMandatory, void *** h ); +extern HB_EXPORT POINT * hbwapi_par_POINT( POINT * p, int iParam, HB_BOOL bMandatory ); +extern HB_EXPORT RECT * hbwapi_par_RECT( RECT * p, int iParam, HB_BOOL bMandatory ); +extern HB_EXPORT DOCINFO * hbwapi_par_DOCINFO( DOCINFO * p, int iParam, HB_BOOL bMandatory, void *** h ); -HB_EXPORT void hbwapi_stor_POINT( POINT * p, int iParam ); -HB_EXPORT void hbwapi_stor_RECT( RECT * p, int iParam ); +extern HB_EXPORT void hbwapi_stor_POINT( POINT * p, int iParam ); +extern HB_EXPORT void hbwapi_stor_RECT( RECT * p, int iParam ); -HB_EXPORT HDC hbwapi_par_HDC( int iParam ); -HB_EXPORT HPEN hbwapi_par_HPEN( int iParam ); -HB_EXPORT HBRUSH hbwapi_par_HBRUSH( int iParam ); -HB_EXPORT HFONT hbwapi_par_HFONT( int iParam ); -HB_EXPORT PDEVMODE hbwapi_par_PDEVMODE( int iParam ); +extern HB_EXPORT HDC hbwapi_par_HDC( int iParam ); +extern HB_EXPORT HPEN hbwapi_par_HPEN( int iParam ); +extern HB_EXPORT HBRUSH hbwapi_par_HBRUSH( int iParam ); +extern HB_EXPORT HFONT hbwapi_par_HFONT( int iParam ); +extern HB_EXPORT PDEVMODE hbwapi_par_PDEVMODE( int iParam ); -HB_EXPORT void hbwapi_ret_HDC( HDC p ); -HB_EXPORT void hbwapi_ret_HPEN( HPEN p ); -HB_EXPORT void hbwapi_ret_HBRUSH( HBRUSH p ); -HB_EXPORT void hbwapi_ret_HFONT( HFONT p ); -HB_EXPORT void hbwapi_ret_PDEVMODE( PDEVMODE p ); +extern HB_EXPORT void hbwapi_ret_HDC( HDC p ); +extern HB_EXPORT void hbwapi_ret_HPEN( HPEN p ); +extern HB_EXPORT void hbwapi_ret_HBRUSH( HBRUSH p ); +extern HB_EXPORT void hbwapi_ret_HFONT( HFONT p ); +extern HB_EXPORT void hbwapi_ret_PDEVMODE( PDEVMODE p ); HB_EXTERN_END diff --git a/harbour/contrib/hbwin/hbwin.h b/harbour/contrib/hbwin/hbwin.h index 401d5ef29a..da0a6cd3f7 100644 --- a/harbour/contrib/hbwin/hbwin.h +++ b/harbour/contrib/hbwin/hbwin.h @@ -77,4 +77,16 @@ #define HB_WIN_COM_DBGQUEUE 0x20 #define HB_WIN_COM_DBGALL 0x3F +/* hbwin_bitmapType() return values */ +#define HB_WIN_BITMAP_UNKNOWN 0 +#define HB_WIN_BITMAP_BMP 1 +#define HB_WIN_BITMAP_JPEG 2 +#define HB_WIN_BITMAP_PNG 3 + +HB_EXTERN_BEGIN + +extern HB_EXPORT int hbwin_bitmapType( const void * pImgBuf, HB_SIZE size ); + +HB_EXTERN_END + #endif /* __HBWIN_H */ diff --git a/harbour/contrib/hbwin/win_bmp.c b/harbour/contrib/hbwin/win_bmp.c index 2925e7fe81..14523ad8b3 100644 --- a/harbour/contrib/hbwin/win_bmp.c +++ b/harbour/contrib/hbwin/win_bmp.c @@ -58,22 +58,13 @@ #include "hbapifs.h" #include "hbapiitm.h" #include "hbwapi.h" -#include "hbwinuni.h" - -#if defined( HB_HAS_PNG ) && defined( HB_HAS_ZLIB ) - #include "png.h" -#endif +#include "hbwin.h" #if ! defined( HB_OS_WIN_CE ) /* Functions for loading & printing bitmaps */ -#define HB_WIN_BITMAP_UNKNOWN 0 -#define HB_WIN_BITMAP_BMP 1 -#define HB_WIN_BITMAP_JPEG 2 -#define HB_WIN_BITMAP_PNG 3 - -static int hbwin_BitmapType( const void * pImgBuf, HB_SIZE size ) +int hbwin_bitmapType( const void * pImgBuf, HB_SIZE size ) { int iType = HB_WIN_BITMAP_UNKNOWN; @@ -92,7 +83,7 @@ static int hbwin_BitmapType( const void * pImgBuf, HB_SIZE size ) HB_FUNC( WIN_BITMAPTYPE ) { - hb_retni( hbwin_BitmapType( hb_parc( 1 ), hb_parclen( 1 ) ) ); + hb_retni( hbwin_bitmapType( hb_parc( 1 ), hb_parclen( 1 ) ) ); } HB_FUNC( WIN_LOADBITMAPFILE ) @@ -115,7 +106,7 @@ HB_FUNC( WIN_LOADBITMAPFILE ) hb_fsSeek( fhnd, 0, FS_SET ); - if( hb_fsReadLarge( fhnd, pbmfh, ulSize ) == ulSize && hbwin_BitmapType( pbmfh, ulSize ) != HB_WIN_BITMAP_UNKNOWN ) + if( hb_fsReadLarge( fhnd, pbmfh, ulSize ) == ulSize && hbwin_bitmapType( pbmfh, ulSize ) != HB_WIN_BITMAP_UNKNOWN ) hb_retclen_buffer( ( char * ) pbmfh, ( HB_SIZE ) ulSize ); else hb_xfree( pbmfh ); @@ -133,7 +124,7 @@ HB_FUNC( WIN_LOADBITMAPFILE ) #define CHECKPNGFORMAT 4120 #endif -static int hbwin_BitmapIsSupported( HDC hDC, int iType, const void * pImgBuf, HB_SIZE nSize ) +static int hbwin_bitmapIsSupported( HDC hDC, int iType, const void * pImgBuf, HB_SIZE nSize ) { if( hDC && iType != HB_WIN_BITMAP_UNKNOWN && @@ -172,7 +163,7 @@ HB_FUNC( WIN_BITMAPISSUPPORTED ) const char * pImgBuf = hb_parc( 2 ); HB_SIZE nSize = hb_parclen( 2 ); - hb_retni( hbwin_BitmapIsSupported( hbwapi_par_HDC( 1 ), hbwin_BitmapType( pImgBuf, nSize ), pImgBuf, nSize ) ); + hb_retni( hbwin_bitmapIsSupported( hbwapi_par_HDC( 1 ), hbwin_bitmapType( pImgBuf, nSize ), pImgBuf, nSize ) ); } HB_FUNC( WIN_DRAWBITMAP ) @@ -182,12 +173,12 @@ HB_FUNC( WIN_DRAWBITMAP ) HDC hDC = hbwapi_par_HDC( 1 ); HB_SIZE nSize = hb_parclen( 2 ); BITMAPFILEHEADER * pbmfh = ( BITMAPFILEHEADER * ) hb_parc( 2 ); - int iType = hbwin_BitmapType( pbmfh, nSize ); + int iType = hbwin_bitmapType( pbmfh, nSize ); /* TOFIX: No check is done on 2nd parameter which is a large security hole and may cause GPF in simple error cases. [vszakats] */ - if( hbwin_BitmapIsSupported( hDC, iType, pbmfh, nSize ) == 0 ) + if( hbwin_bitmapIsSupported( hDC, iType, pbmfh, nSize ) == 0 ) { int iWidth = hb_parni( 7 ); int iHeight = hb_parni( 8 ); @@ -239,268 +230,4 @@ HB_FUNC( WIN_DRAWBITMAP ) hb_retl( HB_FALSE ); } -/* .jpeg size detection code. [vszakats] */ - -#define _JPEG_RET_OK 0 -#define _JPEG_RET_OVERRUN 1 -#define _JPEG_RET_INVALID 2 -#define _JPEG_RET_UNSUPPORTED 3 - -#define _JPEG_CS_GRAY 1 -#define _JPEG_CS_RGB 2 -#define _JPEG_CS_CMYK 3 - -static int hb_jpeg_get_param( const HB_BYTE * buffer, HB_SIZE nBufferSize, int * piHeight, int * piWidth, int * piColorSpace, int * piBPC ) -{ - HB_SIZE nPos = 0; - - HB_U16 tag; - HB_U16 height = 0; - HB_U16 width = 0; - HB_BYTE colorspace = 0; - HB_BYTE bpc = 0; - - if( piHeight ) - *piHeight = 0; - if( piWidth ) - *piWidth = 0; - if( piColorSpace ) - *piColorSpace = 0; - if( piBPC ) - *piBPC = 0; - - if( nPos >= nBufferSize ) - return _JPEG_RET_OVERRUN; - - tag = HB_SWAP_UINT16( ( HB_U16 ) HB_GET_LE_UINT16( buffer + nPos ) ); nPos += 2; - - /* SOI marker */ - if( tag != 0xFFD8 ) - return _JPEG_RET_INVALID; - - for( ;; ) - { - HB_U16 size; - - if( nPos >= nBufferSize ) - return _JPEG_RET_OVERRUN; - - tag = HB_SWAP_UINT16( ( HB_U16 ) HB_GET_LE_UINT16( buffer + nPos ) ); nPos += 2; - - if( nPos >= nBufferSize ) - return _JPEG_RET_OVERRUN; - - size = HB_SWAP_UINT16( ( HB_U16 ) HB_GET_LE_UINT16( buffer + nPos ) ); nPos += 2; - - /* SOF markers */ - if( tag == 0xFFC0 || - tag == 0xFFC1 || - tag == 0xFFC2 || - tag == 0xFFC9 ) - { - if( nPos >= nBufferSize ) - return _JPEG_RET_OVERRUN; - - colorspace = *( buffer + nPos ); nPos += 1; - - if( nPos >= nBufferSize ) - return _JPEG_RET_OVERRUN; - - height = HB_SWAP_UINT16( ( HB_U16 ) HB_GET_LE_UINT16( buffer + nPos ) ); nPos += 2; - - if( nPos >= nBufferSize ) - return _JPEG_RET_OVERRUN; - - width = HB_SWAP_UINT16( ( HB_U16 ) HB_GET_LE_UINT16( buffer + nPos ) ); nPos += 2; - - if( nPos >= nBufferSize ) - return _JPEG_RET_OVERRUN; - - bpc = *( buffer + nPos ); nPos += 1; - - break; - } - else if( ( tag | 0x00FF ) != 0xFFFF ) /* lost marker */ - return _JPEG_RET_UNSUPPORTED; - - nPos += size - 2; - - if( nPos >= nBufferSize ) - return _JPEG_RET_OVERRUN; - } - - if( piHeight ) - *piHeight = ( int ) height; - if( piWidth ) - *piWidth = ( int ) width; - if( piBPC ) - *piBPC = ( int ) bpc; - if( piColorSpace ) - { - switch( colorspace ) - { - case 1: *piColorSpace = _JPEG_CS_GRAY; break; - case 3: *piColorSpace = _JPEG_CS_RGB; break; - case 4: *piColorSpace = _JPEG_CS_CMYK; break; - } - } - - return _JPEG_RET_OK; -} - -/* .png size detection code. [vszakats] */ - -#if defined( HB_HAS_PNG ) && defined( HB_HAS_ZLIB ) - -#define _PNG_RET_OK 0 -#define _PNG_RET_ERR_INVALID1 1 -#define _PNG_RET_ERR_INVALID2 2 -#define _PNG_RET_ERR_INIT1 3 -#define _PNG_RET_ERR_INIT2 4 -#define _PNG_RET_ERR_INIT3 5 -#define _PNG_RET_ERR_READ 6 - -typedef struct -{ - const HB_BYTE * buffer; - HB_SIZE nLen; - HB_SIZE nPos; - HB_BOOL bOk; -} HB_PNG_READ; - -static void hb_png_read_func( png_structp png_ptr, png_bytep data, png_uint_32 length ) -{ - HB_PNG_READ * hb_png_read_data = ( HB_PNG_READ * ) png_get_io_ptr( png_ptr ); - png_uint_32 pos; - - for( pos = 0; pos < length && hb_png_read_data->nPos < hb_png_read_data->nLen; ) - data[ pos++ ] = hb_png_read_data->buffer[ hb_png_read_data->nPos++ ]; - - hb_png_read_data->bOk = ( length == pos ); -} - -static int hb_png_get_param( const HB_BYTE * buffer, HB_SIZE nBufferSize, int * piHeight, int * piWidth, int * piColorSpace, int * piBPC ) -{ - png_structp png_ptr; - png_infop info_ptr; - png_byte header[ 8 ]; - - HB_PNG_READ hb_png_read_data; - int iResult; - - if( piHeight ) - *piHeight = 0; - if( piWidth ) - *piWidth = 0; - if( piColorSpace ) - *piColorSpace = 0; - if( piBPC ) - *piBPC = 0; - - if( nBufferSize < sizeof( header ) ) - return _PNG_RET_ERR_INVALID1; - - memcpy( header, buffer, sizeof( header ) ); - - if( png_sig_cmp( header, ( png_size_t ) 0, sizeof( header ) ) ) - return _PNG_RET_ERR_INVALID2; - - png_ptr = png_create_read_struct( PNG_LIBPNG_VER_STRING, NULL, NULL, NULL ); - if( ! png_ptr ) - return _PNG_RET_ERR_INIT1; - - info_ptr = png_create_info_struct( png_ptr ); - if( ! info_ptr ) - { - png_destroy_read_struct( &png_ptr, ( png_infopp ) NULL, ( png_infopp ) NULL ); - return _PNG_RET_ERR_INIT2; - } - - hb_png_read_data.buffer = buffer; - hb_png_read_data.nLen = nBufferSize; - hb_png_read_data.nPos = sizeof( header ); - hb_png_read_data.bOk = HB_TRUE; - - png_set_sig_bytes( png_ptr, sizeof( header ) ); - png_set_read_fn( png_ptr, ( void * ) &hb_png_read_data, ( png_rw_ptr ) &hb_png_read_func ); - - png_read_info( png_ptr, info_ptr ); - - if( hb_png_read_data.bOk ) - { - png_uint_32 width; - png_uint_32 height; - int bit_depth; - int color_type; - - png_get_IHDR( png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, NULL, NULL, NULL ); - - if( piHeight ) - *piHeight = ( int ) height; - if( piWidth ) - *piWidth = ( int ) width; - if( piBPC ) - *piBPC = bit_depth; - if( piColorSpace ) - *piColorSpace = color_type; - - iResult = _PNG_RET_OK; - } - else - iResult = _PNG_RET_ERR_READ; - - png_destroy_read_struct( &png_ptr, &info_ptr, ( png_infopp ) NULL ); - - return iResult; -} - -#endif - -HB_FUNC( WIN_BITMAPDIMENSIONS ) -{ - const void * buffer = hb_parc( 1 ); - HB_SIZE nSize = hb_parclen( 1 ); - - int iType = hbwin_BitmapType( buffer, nSize ); - - int iHeight = 0; - int iWidth = 0; - HB_BOOL bRetVal = HB_FALSE; - - if( iType == HB_WIN_BITMAP_BMP && nSize >= sizeof( BITMAPCOREHEADER ) ) - { - BITMAPFILEHEADER * pbmfh = ( BITMAPFILEHEADER * ) buffer; - BITMAPINFO * pbmi = ( BITMAPINFO * ) ( pbmfh + 1 ); - - /* Remember there are 2 types of BitMap File */ - if( pbmi->bmiHeader.biSize == sizeof( BITMAPCOREHEADER ) ) - { - iWidth = ( ( BITMAPCOREHEADER * ) pbmi )->bcWidth; - iHeight = ( ( BITMAPCOREHEADER * ) pbmi )->bcHeight; - } - else - { - iWidth = pbmi->bmiHeader.biWidth; - iHeight = abs( pbmi->bmiHeader.biHeight ); - } - - bRetVal = HB_TRUE; - } - else if( iType == HB_WIN_BITMAP_JPEG ) - { - bRetVal = ( hb_jpeg_get_param( ( const HB_BYTE * ) buffer, nSize, &iHeight, &iWidth, NULL, NULL ) == _JPEG_RET_OK ); - } -#if defined( HB_HAS_PNG ) && defined( HB_HAS_ZLIB ) - else if( iType == HB_WIN_BITMAP_PNG ) - { - bRetVal = ( hb_png_get_param( ( const HB_BYTE * ) buffer, nSize, &iHeight, &iWidth, NULL, NULL ) == _PNG_RET_OK ); - } -#endif - - hb_storni( iWidth, 2 ); - hb_storni( iHeight, 3 ); - - hb_retl( bRetVal ); -} - #endif diff --git a/harbour/contrib/hbwin/win_bmpd.c b/harbour/contrib/hbwin/win_bmpd.c new file mode 100644 index 0000000000..7c5ca30a27 --- /dev/null +++ b/harbour/contrib/hbwin/win_bmpd.c @@ -0,0 +1,329 @@ +/* + * $Id$ + */ + +/* + * Harbour Project source code: + * Bitmap dimension detection + * + * Copyright 2010 Viktor Szakats (harbour.01 syenar.hu) + * www - http://www.harbour-project.org + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307 USA (or visit the web site http://www.gnu.org/). + * + * As a special exception, the Harbour Project gives permission for + * additional uses of the text contained in its release of Harbour. + * + * The exception is that, if you link the Harbour libraries with other + * files to produce an executable, this does not by itself cause the + * resulting executable to be covered by the GNU General Public License. + * Your use of that executable is in no way restricted on account of + * linking the Harbour library code into it. + * + * This exception does not however invalidate any other reasons why + * the executable file might be covered by the GNU General Public License. + * + * This exception applies only to the code released by the Harbour + * Project under the name Harbour. If you copy code from other + * Harbour Project or Free Software Foundation releases into a copy of + * Harbour, as the General Public License permits, the exception does + * not apply to the code that you add in this way. To avoid misleading + * anyone as to the status of such modified files, you must delete + * this exception notice from them. + * + * If you write modifications of your own for Harbour, it is your choice + * whether to permit this exception to apply to your modifications. + * If you do not wish that, delete this exception notice. + * + */ + +#define HB_OS_WIN_USED + +#include "hbapi.h" +#include "hbapiitm.h" +#include "hbwin.h" + +#if defined( HB_HAS_PNG ) && defined( HB_HAS_ZLIB ) + #include "png.h" +#endif + +#if ! defined( HB_OS_WIN_CE ) + +/* .jpeg size detection code. [vszakats] */ + +#define _JPEG_RET_OK 0 +#define _JPEG_RET_OVERRUN 1 +#define _JPEG_RET_INVALID 2 +#define _JPEG_RET_UNSUPPORTED 3 + +#define _JPEG_CS_GRAY 1 +#define _JPEG_CS_RGB 2 +#define _JPEG_CS_CMYK 3 + +static int hb_jpeg_get_param( const HB_BYTE * buffer, HB_SIZE nBufferSize, int * piHeight, int * piWidth, int * piColorSpace, int * piBPC ) +{ + HB_SIZE nPos = 0; + + HB_U16 tag; + HB_U16 height = 0; + HB_U16 width = 0; + HB_BYTE colorspace = 0; + HB_BYTE bpc = 0; + + if( piHeight ) + *piHeight = 0; + if( piWidth ) + *piWidth = 0; + if( piColorSpace ) + *piColorSpace = 0; + if( piBPC ) + *piBPC = 0; + + if( nPos >= nBufferSize ) + return _JPEG_RET_OVERRUN; + + tag = HB_SWAP_UINT16( ( HB_U16 ) HB_GET_LE_UINT16( buffer + nPos ) ); nPos += 2; + + /* SOI marker */ + if( tag != 0xFFD8 ) + return _JPEG_RET_INVALID; + + for( ;; ) + { + HB_U16 size; + + if( nPos >= nBufferSize ) + return _JPEG_RET_OVERRUN; + + tag = HB_SWAP_UINT16( ( HB_U16 ) HB_GET_LE_UINT16( buffer + nPos ) ); nPos += 2; + + if( nPos >= nBufferSize ) + return _JPEG_RET_OVERRUN; + + size = HB_SWAP_UINT16( ( HB_U16 ) HB_GET_LE_UINT16( buffer + nPos ) ); nPos += 2; + + /* SOF markers */ + if( tag == 0xFFC0 || + tag == 0xFFC1 || + tag == 0xFFC2 || + tag == 0xFFC9 ) + { + if( nPos >= nBufferSize ) + return _JPEG_RET_OVERRUN; + + colorspace = *( buffer + nPos ); nPos += 1; + + if( nPos >= nBufferSize ) + return _JPEG_RET_OVERRUN; + + height = HB_SWAP_UINT16( ( HB_U16 ) HB_GET_LE_UINT16( buffer + nPos ) ); nPos += 2; + + if( nPos >= nBufferSize ) + return _JPEG_RET_OVERRUN; + + width = HB_SWAP_UINT16( ( HB_U16 ) HB_GET_LE_UINT16( buffer + nPos ) ); nPos += 2; + + if( nPos >= nBufferSize ) + return _JPEG_RET_OVERRUN; + + bpc = *( buffer + nPos ); nPos += 1; + + break; + } + else if( ( tag | 0x00FF ) != 0xFFFF ) /* lost marker */ + return _JPEG_RET_UNSUPPORTED; + + nPos += size - 2; + + if( nPos >= nBufferSize ) + return _JPEG_RET_OVERRUN; + } + + if( piHeight ) + *piHeight = ( int ) height; + if( piWidth ) + *piWidth = ( int ) width; + if( piBPC ) + *piBPC = ( int ) bpc; + if( piColorSpace ) + { + switch( colorspace ) + { + case 1: *piColorSpace = _JPEG_CS_GRAY; break; + case 3: *piColorSpace = _JPEG_CS_RGB; break; + case 4: *piColorSpace = _JPEG_CS_CMYK; break; + } + } + + return _JPEG_RET_OK; +} + +/* .png size detection code. [vszakats] */ + +#if defined( HB_HAS_PNG ) && defined( HB_HAS_ZLIB ) + +#define _PNG_RET_OK 0 +#define _PNG_RET_ERR_INVALID1 1 +#define _PNG_RET_ERR_INVALID2 2 +#define _PNG_RET_ERR_INIT1 3 +#define _PNG_RET_ERR_INIT2 4 +#define _PNG_RET_ERR_INIT3 5 +#define _PNG_RET_ERR_READ 6 + +typedef struct +{ + const HB_BYTE * buffer; + HB_SIZE nLen; + HB_SIZE nPos; + HB_BOOL bOk; +} HB_PNG_READ; + +static void hb_png_read_func( png_structp png_ptr, png_bytep data, png_uint_32 length ) +{ + HB_PNG_READ * hb_png_read_data = ( HB_PNG_READ * ) png_get_io_ptr( png_ptr ); + png_uint_32 pos; + + for( pos = 0; pos < length && hb_png_read_data->nPos < hb_png_read_data->nLen; ) + data[ pos++ ] = hb_png_read_data->buffer[ hb_png_read_data->nPos++ ]; + + hb_png_read_data->bOk = ( length == pos ); +} + +static int hb_png_get_param( const HB_BYTE * buffer, HB_SIZE nBufferSize, int * piHeight, int * piWidth, int * piColorSpace, int * piBPC ) +{ + png_structp png_ptr; + png_infop info_ptr; + png_byte header[ 8 ]; + + HB_PNG_READ hb_png_read_data; + int iResult; + + if( piHeight ) + *piHeight = 0; + if( piWidth ) + *piWidth = 0; + if( piColorSpace ) + *piColorSpace = 0; + if( piBPC ) + *piBPC = 0; + + if( nBufferSize < sizeof( header ) ) + return _PNG_RET_ERR_INVALID1; + + memcpy( header, buffer, sizeof( header ) ); + + if( png_sig_cmp( header, ( png_size_t ) 0, sizeof( header ) ) ) + return _PNG_RET_ERR_INVALID2; + + png_ptr = png_create_read_struct( PNG_LIBPNG_VER_STRING, NULL, NULL, NULL ); + if( ! png_ptr ) + return _PNG_RET_ERR_INIT1; + + info_ptr = png_create_info_struct( png_ptr ); + if( ! info_ptr ) + { + png_destroy_read_struct( &png_ptr, ( png_infopp ) NULL, ( png_infopp ) NULL ); + return _PNG_RET_ERR_INIT2; + } + + hb_png_read_data.buffer = buffer; + hb_png_read_data.nLen = nBufferSize; + hb_png_read_data.nPos = sizeof( header ); + hb_png_read_data.bOk = HB_TRUE; + + png_set_sig_bytes( png_ptr, sizeof( header ) ); + png_set_read_fn( png_ptr, ( void * ) &hb_png_read_data, ( png_rw_ptr ) &hb_png_read_func ); + + png_read_info( png_ptr, info_ptr ); + + if( hb_png_read_data.bOk ) + { + png_uint_32 width; + png_uint_32 height; + int bit_depth; + int color_type; + + png_get_IHDR( png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, NULL, NULL, NULL ); + + if( piHeight ) + *piHeight = ( int ) height; + if( piWidth ) + *piWidth = ( int ) width; + if( piBPC ) + *piBPC = bit_depth; + if( piColorSpace ) + *piColorSpace = color_type; + + iResult = _PNG_RET_OK; + } + else + iResult = _PNG_RET_ERR_READ; + + png_destroy_read_struct( &png_ptr, &info_ptr, ( png_infopp ) NULL ); + + return iResult; +} + +#endif + +HB_FUNC( WIN_BITMAPDIMENSIONS ) +{ + const void * buffer = hb_parc( 1 ); + HB_SIZE nSize = hb_parclen( 1 ); + + int iType = hbwin_bitmapType( buffer, nSize ); + + int iHeight = 0; + int iWidth = 0; + HB_BOOL bRetVal = HB_FALSE; + + if( iType == HB_WIN_BITMAP_BMP && nSize >= sizeof( BITMAPCOREHEADER ) ) + { + BITMAPFILEHEADER * pbmfh = ( BITMAPFILEHEADER * ) buffer; + BITMAPINFO * pbmi = ( BITMAPINFO * ) ( pbmfh + 1 ); + + /* Remember there are 2 types of BitMap File */ + if( pbmi->bmiHeader.biSize == sizeof( BITMAPCOREHEADER ) ) + { + iWidth = ( ( BITMAPCOREHEADER * ) pbmi )->bcWidth; + iHeight = ( ( BITMAPCOREHEADER * ) pbmi )->bcHeight; + } + else + { + iWidth = pbmi->bmiHeader.biWidth; + iHeight = abs( pbmi->bmiHeader.biHeight ); + } + + bRetVal = HB_TRUE; + } + else if( iType == HB_WIN_BITMAP_JPEG ) + { + bRetVal = ( hb_jpeg_get_param( ( const HB_BYTE * ) buffer, nSize, &iHeight, &iWidth, NULL, NULL ) == _JPEG_RET_OK ); + } +#if defined( HB_HAS_PNG ) && defined( HB_HAS_ZLIB ) + else if( iType == HB_WIN_BITMAP_PNG ) + { + bRetVal = ( hb_png_get_param( ( const HB_BYTE * ) buffer, nSize, &iHeight, &iWidth, NULL, NULL ) == _PNG_RET_OK ); + } +#endif + + hb_storni( iWidth, 2 ); + hb_storni( iHeight, 3 ); + + hb_retl( bRetVal ); +} + +#endif diff --git a/harbour/contrib/hbwin/win_tbmp.prg b/harbour/contrib/hbwin/win_tbmp.prg new file mode 100644 index 0000000000..e0f858b635 --- /dev/null +++ b/harbour/contrib/hbwin/win_tbmp.prg @@ -0,0 +1,122 @@ +/* + * $Id$ + */ + +/* + * Harbour Project source code: + * WIN_BMP() class + * + * Copyright 2004 Peter Rees Rees Software & Systems Ltd + * www - http://www.harbour-project.org + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307 USA (or visit the web site http://www.gnu.org/). + * + * As a special exception, the Harbour Project gives permission for + * additional uses of the text contained in its release of Harbour. + * + * The exception is that, if you link the Harbour libraries with other + * files to produce an executable, this does not by itself cause the + * resulting executable to be covered by the GNU General Public License. + * Your use of that executable is in no way restricted on account of + * linking the Harbour library code into it. + * + * This exception does not however invalidate any other reasons why + * the executable file might be covered by the GNU General Public License. + * + * This exception applies only to the code released by the Harbour + * Project under the name Harbour. If you copy code from other + * Harbour Project or Free Software Foundation releases into a copy of + * Harbour, as the General Public License permits, the exception does + * not apply to the code that you add in this way. To avoid misleading + * anyone as to the status of such modified files, you must delete + * this exception notice from them. + * + * If you write modifications of your own for Harbour, it is your choice + * whether to permit this exception to apply to your modifications. + * If you do not wish that, delete this exception notice. + * + */ + +#include "hbclass.ch" +#include "common.ch" + +#include "hbwin.ch" + +CREATE CLASS WIN_BMP + + EXPORTED: + + METHOD New() + METHOD LoadFile( cFileName, aDimXY ) + METHOD Create() + METHOD Destroy() + METHOD IsSupported( oPrn, /* @ */ nError ) + METHOD Draw( oPrn, aRectangle, /* @ */ nError ) + + VAR Type INIT 0 // Type BitMap: 1 == BM, 2 == JPEG, 3 == PNG + VAR DimXY INIT { 0, 0 } // Image Dimensions X Y pixels + VAR Rect INIT { 0, 0, 0, 0 } // Coordinates to print BitMap + // XDest, // x-coord of destination upper-left corner + // YDest, // y-coord of destination upper-left corner + // nDestWidth, // width of destination rectangle + // nDestHeight, // height of destination rectangle + // See WinApi StretchDIBits() + VAR BitMap INIT "" + VAR FileName INIT "" +ENDCLASS + +METHOD New() CLASS WIN_BMP + RETURN Self + +METHOD LoadFile( cFileName, aDimXY ) CLASS WIN_BMP + ::FileName := cFileName + ::Bitmap := win_LoadBitMapFile( ::FileName ) + IF Empty( ::Bitmap ) + ::Type := 0 + ::DimXY := { 0, 0 } + ELSE + ::Type := win_bitmapType( ::Bitmap ) + IF ISARRAY( aDimXY ) + ::DimXY := aDimXY + ELSEIF ! win_BitMapDimensions( ::Bitmap, @::DimXY[ 1 ], @::DimXY[ 2 ] ) + ::DimXY := { 1, 1 } // Driver may use the original dimensions + ENDIF + ENDIF + RETURN ::Type != HB_WIN_BITMAP_UNKNOWN + +METHOD Create() CLASS WIN_BMP // Compatibility function for Alaska Xbase++ + RETURN Self + +METHOD Destroy() CLASS WIN_BMP // Compatibility function for Alaska Xbase++ + RETURN NIL + +METHOD IsSupported( oPrn, /* @ */ nError ) CLASS WIN_BMP + RETURN ( nError := win_BitmapIsSupported( oPrn:hPrinterDc, ::Bitmap ) ) == 0 + +METHOD Draw( oPrn, aRectangle, /* @ */ nError ) CLASS WIN_BMP // Pass a WIN_PRN object reference & Rectangle array + IF ISARRAY( aRectangle ) + ::Rect := aRectangle + ENDIF + RETURN iif( ::IsSupported( oPrn, @nError ), oPrn:DrawBitMap( Self ), .F. ) + +#ifdef HB_COMPAT_XPP + +/* Compatibility Class for Alaska Xbase++ */ + +CREATE CLASS XBPBITMAP FROM WIN_BMP +ENDCLASS + +#endif diff --git a/harbour/contrib/hbwin/win_tprn.prg b/harbour/contrib/hbwin/win_tprn.prg index b08264965a..5cf4cae0fa 100644 --- a/harbour/contrib/hbwin/win_tprn.prg +++ b/harbour/contrib/hbwin/win_tprn.prg @@ -768,74 +768,3 @@ METHOD Inch_To_PosY( nInch ) CLASS WIN_PRN METHOD GetDeviceCaps( nCaps ) CLASS WIN_PRN RETURN win_GetDeviceCaps( ::hPrinterDC, nCaps ) - -/* Bitmap class */ - -CREATE CLASS WIN_BMP - - EXPORTED: - - METHOD New() - METHOD LoadFile( cFileName, aDimXY ) - METHOD Create() - METHOD Destroy() - METHOD Draw( oPrn, aRectangle, aDimXY ) - METHOD IsSupported( oPrn ) - - VAR Type INIT 0 // Type BitMap: 1 == BM, 2 == JPEG, 3 == PNG - VAR DimXY INIT { 0, 0 } // Image Dimensions X Y pixels - VAR Rect INIT { 0, 0, 0, 0 } // Coordinates to print BitMap - // XDest, // x-coord of destination upper-left corner - // YDest, // y-coord of destination upper-left corner - // nDestWidth, // width of destination rectangle - // nDestHeight, // height of destination rectangle - // See WinApi StretchDIBits() - VAR BitMap INIT "" - VAR FileName INIT "" -ENDCLASS - -METHOD New() CLASS WIN_BMP - RETURN Self - -METHOD LoadFile( cFileName, aDimXY ) CLASS WIN_BMP - ::FileName := cFileName - IF ISARRAY( aDimXY ) - ::DimXY := aDimXY - ELSE - ::DimXY := { 1, 1 } // Driver using the original dimensions - ENDIF - ::Bitmap := win_LoadBitMapFile( ::FileName ) - IF Empty( ::Bitmap ) - ::Type := 0 - ::DimXY := { 0, 0 } - ELSE - ::Type := win_bitmapType( ::Bitmap ) - ENDIF - RETURN ::Type != HB_WIN_BITMAP_UNKNOWN - -METHOD Create() CLASS WIN_BMP // Compatibility function for Alaska Xbase++ - RETURN Self - -METHOD Destroy() CLASS WIN_BMP // Compatibility function for Alaska Xbase++ - RETURN NIL - -METHOD Draw( oPrn, aRectangle, aDimXY ) CLASS WIN_BMP // Pass a WIN_PRN object reference & Rectangle array [& Image Dimensions X Y pixels array] - IF ISARRAY( aRectangle ) - ::Rect := aRectangle - ENDIF - IF ISARRAY( aDimXY ) - ::DimXY := aDimXY - ENDIF - RETURN oPrn:DrawBitMap( Self ) - -METHOD IsSupported( oPrn ) CLASS WIN_BMP - RETURN win_BitmapIsSupported( oPrn:hPrinterDc, ::Bitmap ) == 0 - -#ifdef HB_COMPAT_XPP - -/* Compatibility Class for Alaska Xbase++ */ - -CREATE CLASS XBPBITMAP FROM WIN_BMP -ENDCLASS - -#endif