2025-08-29 12:49 UTC+0200 Przemyslaw Czerpak (druzus/at/poczta.onet.pl)
* contrib/hbbmp/core.c
* contrib/hbbmp/hbbmp.ch
* contrib/hbbmp/hbbmp.h
* contrib/hbbmp/hbbmp.hbx
+ added new PRG functions:
hb_bmp_frombitmap( <cBitMap>, <nAlign>, <nWidth>, <nHeight>, ;
[<nDepth>=1], [<nDPI>=72], [<aPalette>], ;
[@<nError>] ) -> <pBMP> | NIL
hb_bmp_colorreset( <pBMP> )
* contrib/hbct/dattime3.c
! struct timespec initialization
* contrib/hbplist.txt
+ added hbbmp library
* contrib/hbzebra/coredraw.c
* contrib/hbzebra/hbzebra.hbx
+ added new PRG function:
hb_zebra_getbitmap( <hZebra>, <nAlign>=8, <lBottomUp>=.F., ;
@<nWidth>, @<nHeight>, <nScaleX>, <nScaleY>, ;
<nBorder> ) -> <cBitMap> | NIL
* contrib/hbzebra/tests/bmp.prg
+ added example for much faster BMP creation using hb_zebra_getbitmap() and
hb_bmp_frombitmap() functions
* src/rtl/filebuf.c
! casting
* src/vm/extrap.c
* allocate stack buffer dynamically, in new Linux version IGSTKSZ is
defined as sysconf( _SC_SIGSTKSZ ) so it cannot be used as legal size
for static arrays
This commit is contained in:
@@ -65,7 +65,11 @@ PHB_BMPINFO hb_bmp_new( int width, int height, int depth, int dpi, int * piError
|
||||
*piError = 0;
|
||||
|
||||
if( fromtop )
|
||||
{
|
||||
height = -height;
|
||||
if( height == 1 )
|
||||
fromtop = HB_FALSE;
|
||||
}
|
||||
if( dpi == 0 )
|
||||
dpi = HB_BMP_DPI_DEFAULT;
|
||||
|
||||
@@ -114,6 +118,72 @@ PHB_BMPINFO hb_bmp_new( int width, int height, int depth, int dpi, int * piError
|
||||
return pBMP;
|
||||
}
|
||||
|
||||
PHB_BMPINFO hb_bmp_frombitmap( const HB_BYTE * bitmap, int align,
|
||||
int width, int height, int depth, int dpi,
|
||||
const int * palette, int colors, int * piError )
|
||||
{
|
||||
static const int mono_palette[ 2 ] = { 0x00FFFFFF, 0x00000000 };
|
||||
PHB_BMPINFO pBMP = NULL;
|
||||
|
||||
if( bitmap && ( align >= 8 || align >= depth ) && ( align & ( align - 1 ) ) == 0 )
|
||||
pBMP = hb_bmp_new( width, height, depth, dpi, piError );
|
||||
else if ( piError )
|
||||
*piError = HB_BMP_ERROR_CORRUPT;
|
||||
|
||||
if( pBMP )
|
||||
{
|
||||
if( bitmap )
|
||||
{
|
||||
int rowbits = ( ( pBMP->width * depth ) + align - 1 ) & ~( align - 1 );
|
||||
int rowlen = ( rowbits + 0x07 ) >> 3, row, col;
|
||||
|
||||
if( align == 32 )
|
||||
memcpy( pBMP->data, bitmap, pBMP->height * pBMP->rowlen );
|
||||
else if( pBMP->height == 1 )
|
||||
memcpy( pBMP->data, bitmap, HB_MIN( rowlen, pBMP->rowlen ) );
|
||||
else if( align >= 8 )
|
||||
{
|
||||
for( row = 0; row < height; ++row )
|
||||
memcpy( pBMP->data + pBMP->rowlen * row, bitmap + rowlen * row,
|
||||
HB_MIN( rowlen, pBMP->rowlen ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
int maskb, shift;
|
||||
|
||||
shift = depth == 4 ? 1 : ( depth == 2 ? 2 : 3 );
|
||||
maskb = ( 0x01 << shift ) - 1;
|
||||
for( row = 0; row < height; ++row )
|
||||
{
|
||||
HB_BYTE * rowdst = pBMP->data + pBMP->rowlen * row;
|
||||
int offset = row * rowbits;
|
||||
for( col = 0; col < width; ++col, offset += depth )
|
||||
rowdst[ col >> shift ] |= ( ( bitmap[ offset >> shift ] >>
|
||||
( ( maskb - ( offset & maskb ) ) * depth ) ) &
|
||||
maskb ) << ( maskb - ( col & maskb ) ) * depth;
|
||||
}
|
||||
}
|
||||
}
|
||||
if( depth == 1 && ( palette == NULL || colors <= 0 ) )
|
||||
{
|
||||
palette = mono_palette;
|
||||
colors = 2;
|
||||
}
|
||||
if( palette && colors > 0 && depth <= 8 )
|
||||
{
|
||||
int i;
|
||||
if( colors > 256 )
|
||||
colors = 256;
|
||||
for( i = 0; i < colors; ++i )
|
||||
{
|
||||
int clr = palette[ i ];
|
||||
hb_bmp_color( pBMP, ( clr >> 16 ) & 0xFF, ( clr >> 8 ) & 0xFF, clr & 0xFF, ( clr >> 24 ) & 0xFF );
|
||||
}
|
||||
}
|
||||
}
|
||||
return pBMP;
|
||||
}
|
||||
|
||||
PHB_BMPINFO hb_bmp_copy( PHB_BMPINFO pBMP )
|
||||
{
|
||||
PHB_BMPINFO pBMPnew = ( PHB_BMPINFO ) hb_xgrab( sizeof( HB_BMPINFO ) );
|
||||
@@ -159,6 +229,12 @@ int hb_bmp_depth( PHB_BMPINFO pBMP )
|
||||
return pBMP->depth;
|
||||
}
|
||||
|
||||
void hb_bmp_colorreset( PHB_BMPINFO pBMP )
|
||||
{
|
||||
memset( pBMP->palette, 0, sizeof( pBMP->palette ) );
|
||||
pBMP->clrused = 0;
|
||||
}
|
||||
|
||||
HB_MAXINT hb_bmp_color( PHB_BMPINFO pBMP, int r, int g, int b, int a )
|
||||
{
|
||||
HB_MAXINT iColor = -1;
|
||||
@@ -460,7 +536,9 @@ PHB_BMPINFO hb_bmp_decode( const HB_BYTE * data, HB_SIZE size, int * piError )
|
||||
PHB_BMPINFO pBMP = NULL;
|
||||
int iError = 0;
|
||||
|
||||
if( ! data || size < HB_BMP_FILEHEADER_SIZE + HB_BMP_INFOHEADER_MINSIZE )
|
||||
if( ! data || size > 0x10000000 )
|
||||
iError = HB_BMP_ERROR_PARAM;
|
||||
else if( size < HB_BMP_FILEHEADER_SIZE + HB_BMP_INFOHEADER_MINSIZE )
|
||||
iError = HB_BMP_ERROR_CORRUPT;
|
||||
else
|
||||
{
|
||||
@@ -691,7 +769,6 @@ void hb_bmpReturn( PHB_BMPINFO pBMP )
|
||||
HB_FUNC( HB_BMP_NEW )
|
||||
{
|
||||
int iError = 0;
|
||||
|
||||
PHB_BMPINFO pBMP = hb_bmp_new( hb_parni( 1 ), hb_parni( 2 ),
|
||||
hb_parnidef( 3, 1 ),
|
||||
hb_parnidef( 4, HB_BMP_DPI_DEFAULT ),
|
||||
@@ -700,6 +777,50 @@ HB_FUNC( HB_BMP_NEW )
|
||||
hb_bmpReturn( pBMP );
|
||||
}
|
||||
|
||||
/* hb_bmp_frombitmap( <cBitMap>, <nAlign>, <nWidth>, <nHeight>, [<nDepth>=1], [<nDPI>=72], [<aPalette>], [@<nError>] ) -> <pBMP> | NIL */
|
||||
HB_FUNC( HB_BMP_FROMBITMAP )
|
||||
{
|
||||
const HB_BYTE * bitmap = ( const HB_BYTE * ) hb_parc( 1 );
|
||||
int align = hb_parni( 2 ), width = hb_parni( 3 ), height = hb_parni( 4 ),
|
||||
depth = hb_parni( 5 ), dpi = hb_parni( 6 ),
|
||||
iError = 0;
|
||||
PHB_ITEM pColors = hb_param( 7, HB_IT_ARRAY );
|
||||
HB_BOOL fromtop = height < 0;
|
||||
PHB_BMPINFO pBMP = NULL;
|
||||
|
||||
if( fromtop )
|
||||
{
|
||||
height = -height;
|
||||
if( height == 1 )
|
||||
fromtop = HB_FALSE;
|
||||
}
|
||||
if( ! bitmap || ( align & ( align - 1 ) ) != 0 ||
|
||||
( HB_SIZE ) ( ( ( width * depth + align - 1 ) & ~( align - 1 ) ) *
|
||||
height + 0x07 ) >> 3 > hb_parclen( 1 ) )
|
||||
iError = HB_BMP_ERROR_PARAM;
|
||||
else
|
||||
{
|
||||
pBMP = hb_bmp_frombitmap( bitmap, align, width, fromtop ? -height : height, depth, dpi,
|
||||
NULL, 0, &iError );
|
||||
if( pBMP && pColors && depth <= 8 )
|
||||
{
|
||||
HB_SIZE nLen = hb_arrayLen( pColors ), nAt;
|
||||
|
||||
if( nLen > ( HB_SIZE ) ( 1 << depth ) )
|
||||
nLen = ( HB_SIZE ) ( 1 << depth );
|
||||
hb_bmp_colorreset( pBMP );
|
||||
for( nAt = 1; nAt <= nLen; ++nAt )
|
||||
{
|
||||
int clr = hb_arrayGetNI( pColors, nAt );
|
||||
hb_bmp_color( pBMP, ( clr >> 16 ) & 0xFF, ( clr >> 8 ) & 0xFF,
|
||||
clr * 0xFF, ( clr >> 24 ) & 0xFF );
|
||||
}
|
||||
}
|
||||
}
|
||||
hb_storni( iError, 8 );
|
||||
hb_bmpReturn( pBMP );
|
||||
}
|
||||
|
||||
HB_FUNC( HB_BMP_COPY )
|
||||
{
|
||||
PHB_BMPINFO pBMP = hb_bmpParam( 1, HB_TRUE );
|
||||
@@ -774,6 +895,14 @@ HB_FUNC( HB_BMP_DEPTH )
|
||||
hb_retni( hb_bmp_depth( pBMP ) );
|
||||
}
|
||||
|
||||
HB_FUNC( HB_BMP_COLORRESET )
|
||||
{
|
||||
PHB_BMPINFO pBMP = hb_bmpParam( 1, HB_TRUE );
|
||||
|
||||
if( pBMP )
|
||||
hb_bmp_colorreset( pBMP );
|
||||
}
|
||||
|
||||
HB_FUNC( HB_BMP_COLOR )
|
||||
{
|
||||
PHB_BMPINFO pBMP = hb_bmpParam( 1, HB_TRUE );
|
||||
|
||||
@@ -59,5 +59,6 @@
|
||||
#define HB_BMP_ERROR_UNSUPPORTED 8
|
||||
#define HB_BMP_ERROR_FILEREAD 9
|
||||
#define HB_BMP_ERROR_FILEWRITE 10
|
||||
#define HB_BMP_ERROR_PARAM 11
|
||||
|
||||
#endif /* _HBBMP_CH_ */
|
||||
|
||||
@@ -112,6 +112,7 @@ typedef struct _HB_BMPINFO
|
||||
} HB_BMPINFO, * PHB_BMPINFO;
|
||||
|
||||
extern HB_EXPORT PHB_BMPINFO hb_bmp_new( int width, int height, int depth, int dpi, int * piError );
|
||||
extern HB_EXPORT PHB_BMPINFO hb_bmp_frombitmap( const HB_BYTE * bitmap, int align, int width, int height, int depth, int dpi, const int * palette, int colors, int * piError );
|
||||
extern HB_EXPORT PHB_BMPINFO hb_bmp_copy( PHB_BMPINFO pBMP );
|
||||
extern HB_EXPORT PHB_BMPINFO hb_bmp_decode( const HB_BYTE * data, HB_SIZE size, int * piError );
|
||||
extern HB_EXPORT HB_BYTE * hb_bmp_encode( PHB_BMPINFO pBMP, HB_SIZE * pnSsize );
|
||||
@@ -122,6 +123,7 @@ extern HB_EXPORT int hb_bmp_error( PHB_BMPINFO pBMP );
|
||||
extern HB_EXPORT int hb_bmp_width( PHB_BMPINFO pBMP );
|
||||
extern HB_EXPORT int hb_bmp_height( PHB_BMPINFO pBMP );
|
||||
extern HB_EXPORT int hb_bmp_depth( PHB_BMPINFO pBMP );
|
||||
extern HB_EXPORT void hb_bmp_colorreset( PHB_BMPINFO pBMP );
|
||||
extern HB_EXPORT HB_MAXINT hb_bmp_color( PHB_BMPINFO pBMP, int r, int g, int b, int a );
|
||||
extern HB_EXPORT HB_BOOL hb_bmp_color2rgb( PHB_BMPINFO pBMP, HB_MAXINT clr, int * r, int * g, int * b, int * a );
|
||||
extern HB_EXPORT HB_BOOL hb_bmp_putpixel( PHB_BMPINFO pBMP, int x, int y, HB_MAXINT clr );
|
||||
|
||||
@@ -23,12 +23,14 @@
|
||||
|
||||
DYNAMIC hb_bmp_color
|
||||
DYNAMIC hb_bmp_color2rgb
|
||||
DYNAMIC hb_bmp_colorreset
|
||||
DYNAMIC hb_bmp_copy
|
||||
DYNAMIC hb_bmp_decode
|
||||
DYNAMIC hb_bmp_depth
|
||||
DYNAMIC hb_bmp_encode
|
||||
DYNAMIC HB_BMP_ERROR
|
||||
DYNAMIC hb_bmp_error
|
||||
DYNAMIC hb_bmp_free
|
||||
DYNAMIC hb_bmp_frombitmap
|
||||
DYNAMIC hb_bmp_getpixel
|
||||
DYNAMIC hb_bmp_height
|
||||
DYNAMIC hb_bmp_line
|
||||
|
||||
@@ -195,7 +195,7 @@ HB_FUNC( SETDATE )
|
||||
long lNewDate = lDate - hb_dateEncode( 1970, 1, 1 );
|
||||
# if defined( __GLIBC__ ) && ( ( __GLIBC__ > 2 ) || ( ( __GLIBC__ == 2 ) && ( __GLIBC_MINOR__ >= 31 ) ) )
|
||||
/* stime() is deprecated in glibc 2.31+ */
|
||||
struct timespec ts = { 0 };
|
||||
struct timespec ts = { 0, 0 };
|
||||
clock_gettime( CLOCK_REALTIME, &ts ); /* keep tv_nsec */
|
||||
ts.tv_sec = lNewDate * 86400 + ( ts.tv_sec % 86400 );
|
||||
fResult = clock_settime( CLOCK_REALTIME, &ts ) == 0;
|
||||
|
||||
@@ -4,6 +4,7 @@ gtwvg/gtwvg.hbp
|
||||
hbamf/hbamf.hbp
|
||||
hbblat/hbblat.hbp
|
||||
hbblink/hbblink.hbp
|
||||
hbbmp/hbbmp.hbp
|
||||
hbbz2/hbbz2.hbp # uses: bz2 (locally hosted)
|
||||
hbbz2io/hbbz2io.hbp # uses: bz2 (locally hosted)
|
||||
hbcairo/hbcairo.hbp
|
||||
|
||||
@@ -171,6 +171,7 @@ int hb_zebra_getsize( PHB_ZEBRA pZebra, int * piWidth, int * piHeight )
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* hb_zebra_getsize( <hZebra>, @<nWidth>, @<nHeight> ) -> <nError> */
|
||||
HB_FUNC( HB_ZEBRA_GETSIZE )
|
||||
{
|
||||
PHB_ZEBRA pZebra = hb_zebra_param( 1 );
|
||||
@@ -184,3 +185,94 @@ HB_FUNC( HB_ZEBRA_GETSIZE )
|
||||
hb_storni( iHeight, 3 );
|
||||
}
|
||||
}
|
||||
|
||||
/* NOTE: caller must free the returned bitmap pointer if not NULL */
|
||||
unsigned char * hb_zebra_getbitmap( PHB_ZEBRA pZebra, int iAlign, HB_BOOL fBottomUp,
|
||||
HB_SIZE * pnSize, int * piWidth, int * piHeight,
|
||||
int iScaleX, int iScaleY, int iBorder )
|
||||
{
|
||||
unsigned char * pBitMap = NULL;
|
||||
HB_SIZE nSize = 0;
|
||||
int iWidth, iHeight;
|
||||
|
||||
if( hb_zebra_getsize( pZebra, &iWidth, &iHeight ) == 0 &&
|
||||
iWidth != 0 && iHeight != 0 )
|
||||
{
|
||||
HB_SIZE nLen = hb_bitbuffer_len( pZebra->pBits ), n;
|
||||
int iLineBits, iLineOffset, iMaxCol, iCol;
|
||||
|
||||
if( iAlign < 1 || iAlign > 64 || ( iAlign & ( iAlign - 1 ) ) != 0 )
|
||||
iAlign = 8;
|
||||
if( iScaleX < 1 )
|
||||
iScaleX = 1;
|
||||
if( iScaleY < 1 )
|
||||
iScaleY = 1;
|
||||
if( iBorder < 0 )
|
||||
iBorder = 0;
|
||||
iWidth = iWidth * iScaleX + ( iBorder << 1 );
|
||||
iHeight = iHeight * iScaleY + ( iBorder << 1 );
|
||||
iLineBits = ( iWidth + ( iAlign - 1 ) ) & ~( iAlign - 1 );
|
||||
nSize = ( iLineBits * iHeight + 0x07 ) >> 3;
|
||||
if( nLen > ( nSize << 3 ) )
|
||||
nLen = nSize << 3;
|
||||
pBitMap = ( unsigned char * ) hb_xgrab( nSize + 1 );
|
||||
|
||||
iMaxCol = pZebra->iCol;
|
||||
iCol = 0;
|
||||
if( fBottomUp )
|
||||
iLineOffset = iLineBits * ( iHeight - iBorder - 1 );
|
||||
else
|
||||
iLineOffset = iLineBits * iBorder;
|
||||
|
||||
memset( pBitMap, 0, nSize );
|
||||
for( n = 0; n < nLen; n++ )
|
||||
{
|
||||
if( hb_bitbuffer_get( pZebra->pBits, n ) )
|
||||
{
|
||||
int iBitPos = iLineOffset + iCol * iScaleX + iBorder, iX, iY;
|
||||
for( iY = 0; iY < iScaleY; ++iY )
|
||||
{
|
||||
for( iX = 0; iX < iScaleX; ++iX )
|
||||
{
|
||||
unsigned char * ptr = pBitMap + ( ( iBitPos + iX ) >> 3 );
|
||||
*ptr |= 0x80 >> ( ( iBitPos + iX ) & 0x07 );
|
||||
}
|
||||
iBitPos += fBottomUp ? - iLineBits : iLineBits;
|
||||
}
|
||||
}
|
||||
if( ++iCol == iMaxCol )
|
||||
{
|
||||
iCol = 0;
|
||||
iLineOffset += ( fBottomUp ? - iLineBits : iLineBits ) * iScaleY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*pnSize = nSize;
|
||||
*piWidth = iWidth;
|
||||
*piHeight = iHeight;
|
||||
|
||||
return pBitMap;
|
||||
}
|
||||
|
||||
/* hb_zebra_getbitmap( <hZebra>, <nAlign>=8, <lBottomUp>=.F., @<nWidth>, @<nHeight>, <nScaleX>, <nScaleY>, <nBorder> ) -> <cBitMap> | NIL */
|
||||
HB_FUNC( HB_ZEBRA_GETBITMAP )
|
||||
{
|
||||
PHB_ZEBRA pZebra = hb_zebra_param( 1 );
|
||||
|
||||
if( pZebra )
|
||||
{
|
||||
HB_SIZE nSize;
|
||||
int iWidth, iHeight;
|
||||
unsigned char * pBitMap = hb_zebra_getbitmap( pZebra, hb_parni( 2 ), hb_parl( 3 ),
|
||||
&nSize, &iWidth, &iHeight,
|
||||
hb_parni( 6 ), hb_parni( 7 ), hb_parni( 8 ) );
|
||||
|
||||
hb_storni( iWidth, 4 );
|
||||
hb_storni( iHeight, 5 );
|
||||
if( pBitMap )
|
||||
hb_retclen_buffer( ( char * ) pBitMap, nSize );
|
||||
else
|
||||
hb_retc_null();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,6 +37,7 @@ DYNAMIC hb_zebra_create_upca
|
||||
DYNAMIC hb_zebra_create_upce
|
||||
DYNAMIC hb_zebra_destroy
|
||||
DYNAMIC hb_zebra_draw
|
||||
DYNAMIC hb_zebra_getbitmap
|
||||
DYNAMIC hb_zebra_getcode
|
||||
DYNAMIC hb_zebra_geterror
|
||||
DYNAMIC hb_zebra_getsize
|
||||
|
||||
@@ -33,7 +33,8 @@ PROCEDURE Main()
|
||||
|
||||
STATIC PROCEDURE DrawBarcode( nLineWidth, cType, cCode, nFlags )
|
||||
|
||||
LOCAL hZebra, pBMP, nLineHeight, nX, nY, nWidth, nHeight, nDepth, nColor, cFile
|
||||
LOCAL hZebra, cFile, cBitMap, pBMP, ;
|
||||
nLineHeight, nX, nY, nWidth, nHeight, nDepth, nAlign, nColor
|
||||
|
||||
SWITCH cType
|
||||
CASE "EAN13" ; hZebra := hb_zebra_create_ean13( cCode, nFlags ) ; EXIT
|
||||
@@ -59,13 +60,13 @@ STATIC PROCEDURE DrawBarcode( nLineWidth, cType, cCode, nFlags )
|
||||
nLineHeight := nLineWidth * 36
|
||||
ENDIF
|
||||
|
||||
nAlign := 32
|
||||
nDepth := 1
|
||||
nX := nY := 1
|
||||
/* get barcode size and add 1 pixel border over it */
|
||||
hb_zebra_getsize( hZebra, @nWidth, @nHeight )
|
||||
nX := 1
|
||||
nY := 1
|
||||
nWidth := nWidth * nLineWidth + 2
|
||||
nHeight := nHeight * nLineHeight + 2
|
||||
nWidth := nWidth * nLineWidth + nY + nY
|
||||
nHeight := nHeight * nLineHeight + nX + nX
|
||||
|
||||
? cType, "code width", hb_ntos( nWidth ), "height", hb_ntos( nHeight )
|
||||
IF Empty( pBMP := hb_bmp_new( nWidth, nHeight, nDepth ) )
|
||||
@@ -86,6 +87,18 @@ STATIC PROCEDURE DrawBarcode( nLineWidth, cType, cCode, nFlags )
|
||||
/* destroy BMP file */
|
||||
pBMP := NIL
|
||||
ENDIF
|
||||
|
||||
/* and now much faster version */
|
||||
cBitMap := hb_zebra_getbitmap( hZebra, nAlign, .T./*lBottomUp>*/, @nWidth, @nHeight, nLineWidth, nLineHeight, nX )
|
||||
pBMP := hb_bmp_frombitmap( cBitMap, nAlign, nWidth, nHeight, nDepth, /*nDPI*/, /*aPalette*/, /*@nError*/ )
|
||||
cFile := Lower( cType ) + "b.bmp"
|
||||
? "Creating BMP file:", cFile
|
||||
IF ! hb_bmp_save( pBMP, cFile )
|
||||
? "Cannot save BMP to file:", cFile
|
||||
ENDIF
|
||||
/* destroy BMP file */
|
||||
pBMP := NIL
|
||||
|
||||
ELSE
|
||||
? "Type", cType, "Code", cCode, "Error", hb_zebra_geterror( hZebra )
|
||||
ENDIF
|
||||
|
||||
Reference in New Issue
Block a user