/* * saveBitmapFile - gets the bitmap data and saves it in fname. */ static bool saveBitmapFile( img_node *node ) { BITMAPARRAYFILEHEADER2 new_file; BITMAPINFO2 *bmi; long clrtable_size; RGB2 *colours; FILE *fp; char text[ HINT_TEXT_LEN ]; char filename[ _MAX_FNAME ]; bool ok; ok = false; bmi = GetXorBitmapInfo(node); if( bmi != NULL ) { clrtable_size = sizeof( RGB2 ) * ( 1 << ( node->bitcount ) ); new_file.usType = BFT_BITMAPARRAY; new_file.cbSize = sizeof( BITMAPARRAYFILEHEADER2 ); new_file.offNext = 0; new_file.cxDisplay = 0; new_file.cyDisplay = 0; new_file.bfh2.usType = BFT_BMAP; new_file.bfh2.cbSize = sizeof( BITMAPFILEHEADER2 ); new_file.bfh2.xHotspot = 0; new_file.bfh2.yHotspot = 0; new_file.bfh2.offBits = new_file.cbSize + clrtable_size; memcpy( &(new_file.bfh2.bmp2), bmi, sizeof( BITMAPINFOHEADER2 ) ); colours = (void *)&(bmi->argbColor[0]); fp = fopen( node->fname, "wb" ); if( fp != NULL ) { if( fseek( fp, 0L, SEEK_SET ) == 0 ) { if( fwrite( &new_file, sizeof( BITMAPARRAYFILEHEADER2 ), 1, fp ) == 1 ) { if( fwrite( colours, clrtable_size, 1, fp ) == 1 ) { if( writeDataInPieces( bmi, fp, node ) ) { ok = true; } else { MessageBox( HMainWindow, "Error writing file!", "Error", MB_OK | MB_ICONEXCLAMATION ); SetHintText( "Error saving file" ); } } } } fclose( fp ); } FreeDIBitmapInfo( bmi ); if( ok ) { AllowRestoreOption( node ); SetIsSaved( node->hwnd, TRUE ); GetFnameFromPath( node->fname, filename ); sprintf( text, "Bitmap saved to '%s'", filename ); SetHintText( text ); } } return( ok ); } /* saveBitmapFile */
/* * ConvertToDIBitmap - convert the device dependent bitmap to a DI bitmap */ void ConvertToDIBitmap( HBITMAP hbitmap ) { HDC hdc; BITMAPINFO *bmi; BYTE *bits; BITMAP bm; img_node *node; /* * Fill the info structure with information about the current image * we are editing. */ node = GetCurrentNode(); bmi = GetDIBitmapInfo( node ); GetObject( hbitmap, sizeof( BITMAP ), &bm ); /* * Replace the fields on the info header with values for *this* bitmap. */ bmi->bmiHeader.biWidth = bm.bmWidth; bmi->bmiHeader.biHeight = bm.bmHeight; #if 0 if( bmi->bmiHeader.bmWidth > 32 ) { bmi->bmiHeader.biSizeImage = BITS_INTO_BYTES( bmi->bmiHeader.biBitCount * bm.bmWidth, bm.bmHeight ); } else { bmi->bmiHeader.biSizeImage = BITS_TO_BYTES( bmi->bmiHeader.biBitCount * bm.bmWidth, bm.bmHeight ); } #else bmi->bmiHeader.biSizeImage = BITS_TO_BYTES( bmi->bmiHeader.biBitCount * bm.bmWidth, bm.bmHeight ); #endif bits = MemAlloc( bmi->bmiHeader.biSizeImage ); hdc = GetDC( NULL ); GetDIBits( hdc, hbitmap, 0, bmi->bmiHeader.biHeight, bits, bmi, DIB_RGB_COLORS ); SetDIBits( hdc, hbitmap, 0, bmi->bmiHeader.biHeight, bits, bmi, DIB_RGB_COLORS ); ReleaseDC( NULL, hdc ); FreeDIBitmapInfo( bmi ); MemFree( bits ); } /* ConvertToDIBitmap */
/* * writeImageBits - writes the bits for the image */ static bool writeImageBits( FILE *fp, img_node *node ) { WPI_PRES pres; WPI_PRES mempres; HDC memdc; ULONG byte_count; img_node *new_image; BITMAPINFO2 *bmi; HBITMAP oldbitmap; HBITMAP inverse_bitmap; HBITMAP clr_bitmap; BYTE *buffer; bool ok; ok = true; pres = _wpi_getpres( HWND_DESKTOP ); mempres = _wpi_createcompatiblepres( pres, Instance, &memdc ); _wpi_releasepres( HWND_DESKTOP, pres ); for( new_image = node; new_image != NULL; new_image = new_image->nexticon ) { bmi = GetAndBitmapInfo(new_image); if( bmi == NULL ) { ok = false; break; } /* * first we write the PM XOR mask (inverse mask) then the PM AND * mask (and mask) and then the PM colour mask (xor mask). */ byte_count = BITS_TO_BYTES( new_image->width, new_image->height ); buffer = MemAlloc( byte_count ); inverse_bitmap = CreateInverseBitmap( new_image->handbitmap, new_image->hxorbitmap ); oldbitmap = _wpi_selectobject( mempres, inverse_bitmap ); GpiQueryBitmapBits( mempres, 0, new_image->height, buffer, bmi ); fwrite( buffer, sizeof( BYTE ), byte_count, fp ); _wpi_selectobject( mempres, oldbitmap ); _wpi_deletebitmap( inverse_bitmap ); oldbitmap = _wpi_selectobject( mempres, new_image->handbitmap ); GpiQueryBitmapBits( mempres, 0, new_image->height, buffer, bmi ); fwrite( buffer, sizeof( BYTE ), byte_count, fp ); _wpi_selectobject( mempres, oldbitmap ); MemFree( buffer ); FreeDIBitmapInfo( bmi ); bmi = GetXorBitmapInfo( new_image ); if( bmi == NULL ) { ok = false; break; } clr_bitmap = CreateColourBitmap( new_image->handbitmap, new_image->hxorbitmap ); oldbitmap = _wpi_selectobject( mempres, clr_bitmap ); byte_count = BITS_TO_BYTES( new_image->width * new_image->bitcount, new_image->height ); buffer = MemAlloc( byte_count ); GpiQueryBitmapBits( mempres, 0, node->height, buffer, bmi ); fwrite( buffer, sizeof( BYTE ), byte_count, fp ); MemFree( buffer ); FreeDIBitmapInfo( bmi ); _wpi_selectobject( mempres, oldbitmap ); _wpi_deletebitmap( clr_bitmap ); } _wpi_deletecompatiblepres( mempres, memdc ); return( ok ); } /* writeImageBits */
/* * saveImageFile - saves a cursor or icon file */ static bool saveImageFile( img_node *node ) { BITMAPARRAYFILEHEADER2 new_file; BITMAPFILEHEADER2 *and_part; BITMAPFILEHEADER2 *xor_part; BITMAPINFO2 *andbmi; BITMAPINFO2 *xorbmi; long clrtable_size; long and_size; ULONG nextoff; RGB2 *colours; FILE *fp; char text[ HINT_TEXT_LEN ]; char filename[ _MAX_FNAME ]; img_node *new_image; bool ok; ok = false; fp = fopen( node->fname, "wb" ); if( fp != NULL ) { if( fseek( fp, 0L, SEEK_SET ) == 0 ) { ok = true; nextoff = 0; for( new_image = node; new_image != NULL; new_image = new_image->nexticon ) { new_file.usType = BFT_BITMAPARRAY; new_file.cbSize = sizeof( BITMAPARRAYFILEHEADER2 ); new_file.offNext = nextoff; new_file.cxDisplay = 0; new_file.cyDisplay = 0; and_part = fillFileHeader( new_image ); memcpy( &(new_file.bfh2), and_part, sizeof( BITMAPFILEHEADER2 ) ); /* * First the info for the AND mask */ andbmi = GetAndBitmapInfo( new_image ); if( andbmi == NULL ) { ok = false; } else { clrtable_size = sizeof( RGB2 ) * ( 1 << new_image->bitcount ); and_size = sizeof( RGB2 ) * 2; new_file.bfh2.offBits = new_file.offNext + new_file.cbSize + and_size + clrtable_size + sizeof( BITMAPFILEHEADER2 ); memcpy( &(new_file.bfh2.bmp2), andbmi, sizeof( BITMAPINFOHEADER2 ) ); colours = (void *)&(andbmi->argbColor[0]); if( fwrite( &new_file, sizeof( BITMAPARRAYFILEHEADER2 ), 1, fp ) != 1 ) { ok = false; } else if( fwrite( colours, and_size, 1, fp ) != 1 ) { ok = false; } FreeDIBitmapInfo( andbmi ); } MemFree( and_part ); if( ok ) { /* * Now we write the XOR part */ xor_part = fillFileHeader( new_image ); xorbmi = GetXorBitmapInfo( new_image ); if( xorbmi == NULL ) { ok = false; } else { xor_part->offBits = new_file.bfh2.offBits + BITS_TO_BYTES( new_image->width, 2 * new_image->height ); memcpy( &(xor_part->bmp2), xorbmi, sizeof( BITMAPINFOHEADER2 ) ); colours = (void *)&(xorbmi->argbColor[0]); if( fwrite( xor_part, sizeof( BITMAPFILEHEADER2 ), 1, fp ) != 1 ) { ok = false; } else if( fwrite( colours, clrtable_size, 1, fp ) != 1 ) { ok = false; } FreeDIBitmapInfo( xorbmi ); } MemFree( xor_part ); nextoff = nextoff + sizeof( BITMAPARRAYFILEHEADER2 ) + and_size + sizeof( BITMAPFILEHEADER2 ) + clrtable_size; } if( !rc ) { break; } } } fclose( fp ); } if( ok ) { /* * Now we write the bits for all the images in the file. */ if( !writeImageBits( fp, node ) ) { return( false ); } AllowRestoreOption( node ); SetIsSaved( node->hwnd, TRUE ); GetFnameFromPath( node->fname, filename ); if( node->imgtype == ICON_IMG ) { sprintf( text, "Icon saved to '%s'", filename ); } else { sprintf( text, "Pointer saved to '%s'", filename ); } SetHintText( text ); } return( ok ); } /* saveImageFile */