// ******************************************************************************* // FUNCTION: GetBitmapFromClipboard // // FUNCTION USE: Retrieves bitmap data from the clipboard // // DESCRIPTION: This function is used to handle the paste functionality, by // retrieving bitmap data (CF_BITMAP) from the clipboard. The // function will set a bitmap into an HPS if passed a valid PS // handle. // // NOTE: This routine has been slightly modified from the routine // used in the Chapter 4 sample program. // // PARAMETERS: HPS Presentation space handle to place the bitmap in. // // RETURNS: TRUE success // FALSE error // // HISTORY: // // ******************************************************************************* HBITMAP GetBitmapFromClipboard(HPS hpsSource) { HAB habTemp; HBITMAP hbmTemp; APIRET rc; static HBITMAP hbmClip; // -------------------------------------------------------------------------- // Get an anchor block handle // -------------------------------------------------------------------------- habTemp = WinQueryAnchorBlock(HWND_DESKTOP); // -------------------------------------------------------------------------- // Open the clipboard // -------------------------------------------------------------------------- rc = WinOpenClipbrd (habTemp); // -------------------------------------------------------------------------- // If we get an error opening, return FALSE and post message // -------------------------------------------------------------------------- if (!rc) { return rc; } // -------------------------------------------------------------------------- // Get the bitmap data out of the clipboard // -------------------------------------------------------------------------- hbmTemp = (HBITMAP) WinQueryClipbrdData (habTemp, CF_BITMAP); // -------------------------------------------------------------------------- // WinQueryClipbrdData will return a NULLHANDLE if there is no // bitmap data in the clipboard or if an error occurred. // -------------------------------------------------------------------------- if (hbmTemp != NULLHANDLE) { // -------------------------------------------------------------------------- // Duplicate our bitmap handle. // -------------------------------------------------------------------------- hbmClip = DuplicateBitmap (hbmTemp, hpsSource); if (hbmClip == NULLHANDLE) { DisplayMessages(NULLHANDLE, "Error Duplicating Bitmap", MSG_EXCLAMATION); } } // -------------------------------------------------------------------------- // Close the clipboard and return our bitmap handle // -------------------------------------------------------------------------- WinCloseClipbrd (habTemp); return hbmClip; }
void ColorBalanceManipulator::SetPreviewBitmap(BBitmap *bm) { if (preview_bitmap != bm) { delete copy_of_the_preview_bitmap; if (bm != NULL) { preview_bitmap = bm; copy_of_the_preview_bitmap = DuplicateBitmap(bm,0); } else { preview_bitmap = NULL; copy_of_the_preview_bitmap = NULL; } } }
void SaturationManipulator::SetPreviewBitmap(BBitmap *bm) { if (preview_bitmap != bm) { delete copy_of_the_preview_bitmap; delete luminance_image; if (bm != NULL) { preview_bitmap = bm; copy_of_the_preview_bitmap = DuplicateBitmap(bm,0); luminance_image = new BBitmap(preview_bitmap->Bounds(),B_CMAP8); CalculateLuminanceImage(preview_bitmap); } else { preview_bitmap = NULL; copy_of_the_preview_bitmap = NULL; luminance_image = NULL; } } if (preview_bitmap != NULL) { BeOS_system_info info; get_BeOS_system_info(&info); double speed = info.cpu_count * info.cpu_clock_speed; // Let's select a resolution that can handle all the pixels at least // 10 times in a second while assuming that one pixel calculation takes // about 50 CPU cycles. speed = speed / (10*50); BRect bounds = preview_bitmap->Bounds(); float num_pixels = (bounds.Width()+1) * (bounds.Height() + 1); lowest_available_quality = 1; while ((num_pixels/lowest_available_quality/lowest_available_quality) > speed) lowest_available_quality *= 2; lowest_available_quality = min_c(lowest_available_quality,16); highest_available_quality = max_c(lowest_available_quality/2,1); } else { lowest_available_quality = 1; highest_available_quality = 1; } last_calculated_resolution = lowest_available_quality; }
/* * ShiftImage - shift the image in the given direction */ void ShiftImage( WORD shiftdirection ) { HBITMAP dup_and; HBITMAP dup_xor; HBITMAP oldbitmap; HBITMAP oldsrcbitmap; WPI_PRES pres; HDC memdc; WPI_PRES mempres; HDC srcdc; WPI_PRES srcpres; short x_src; short y_src; short x_dest; short y_dest; short width; short height; short min_width; short min_height; short rgn_width; short rgn_height; img_node *node; WPI_RECT rect; IMGED_DIM left; IMGED_DIM right; IMGED_DIM top; IMGED_DIM bottom; DWORD message; node = GetCurrentNode(); if( node == NULL ) { return; } dup_and = DuplicateBitmap( node->handbitmap ); dup_xor = DuplicateBitmap( node->hxorbitmap ); pres = _wpi_getpres( HWND_DESKTOP ); mempres = _wpi_createcompatiblepres( pres, Instance, &memdc ); srcpres = _wpi_createcompatiblepres( pres, Instance, &srcdc ); _wpi_releasepres( HWND_DESKTOP, pres ); _wpi_torgbmode( mempres ); _wpi_torgbmode( srcpres ); if( DoesRectExist( &rect ) ) { width = (short)_wpi_getwidthrect( rect ); height = (short)_wpi_getheightrect( rect ); } else { _wpi_setwrectvalues( &rect, 0, 0, node->width, node->height ); width = node->width; height = node->height; } _wpi_getwrectvalues( rect, &left, &top, &right, &bottom ); oldbitmap = _wpi_selectobject( mempres, node->handbitmap ); _wpi_patblt( mempres, left, top, width, height, BLACKNESS ); _wpi_selectobject( mempres, oldbitmap ); oldbitmap = _wpi_selectobject( mempres, node->hxorbitmap ); _wpi_patblt( mempres, left, top, width, height, WHITENESS ); oldsrcbitmap = _wpi_selectobject( srcpres, dup_xor ); x_src = (short)left; y_src = (short)top; x_dest =(short)left; y_dest = (short)top; min_width = (short)min( ImgedConfigInfo.shift, width ); min_height = (short)min( ImgedConfigInfo.shift, height ); rgn_width = width; rgn_height = height; switch( shiftdirection ) { case IMGED_LEFT: width -= min_width; x_src = x_src + min_width; message = WIE_IMAGESHIFTEDLEFT; break; case IMGED_RIGHT: width -= min_width; x_dest = x_dest + min_width; message = WIE_IMAGESHIFTEDRIGHT; break; case IMGED_UP: #ifndef __OS2_PM__ height -= min_height; y_src = y_src + min_height; #else height += min_height; y_src = y_src - min_height; #endif message = WIE_IMAGESHIFTEDUP; break; case IMGED_DOWN: #ifndef __OS2_PM__ height -= min_height; y_dest = y_dest + min_height; #else height += min_height; y_dest = y_dest - min_height; #endif message = WIE_IMAGESHIFTEDDOWN; break; default: break; } _wpi_bitblt( mempres, x_dest, y_dest, width, height, srcpres, x_src, y_src, SRCCOPY ); _wpi_selectobject( srcpres, oldsrcbitmap ); oldsrcbitmap = _wpi_selectobject( srcpres, dup_and ); _wpi_selectobject( mempres, oldbitmap ); oldbitmap = _wpi_selectobject( mempres, node->handbitmap ); _wpi_bitblt( mempres, x_dest, y_dest, width, height, srcpres, x_src, y_src, SRCCOPY ); if( IsShiftWrap() ) { switch( shiftdirection ) { case IMGED_LEFT: width = min_width; x_src = (short)left; x_dest = (short)(right - width); break; case IMGED_RIGHT: width = min_width; x_dest = (short)left; x_src = (short)(right - width); break; case SHIFT_UP: height = min_height; y_src = (short)top; y_dest = (short)(bottom - height); break; case SHIFT_DOWN: height = min_height; y_dest = (short)top; y_src = (short)(bottom - height); break; default: break; } _wpi_bitblt( mempres, x_dest, y_dest, width, height, srcpres, x_src, y_src, SRCCOPY ); _wpi_selectobject( srcpres, oldsrcbitmap ); _wpi_selectobject( mempres, oldbitmap ); oldsrcbitmap = _wpi_selectobject( srcpres, dup_xor ); oldbitmap = _wpi_selectobject( mempres, node->hxorbitmap ); _wpi_bitblt( mempres, x_dest, y_dest, width, height, srcpres, x_src, y_src, SRCCOPY ); } _wpi_selectobject( srcpres, oldsrcbitmap ); _wpi_selectobject( mempres, oldbitmap ); _wpi_deletecompatiblepres( srcpres, srcdc ); _wpi_deletecompatiblepres( mempres, memdc ); _wpi_deleteobject( dup_xor ); _wpi_deleteobject( dup_and ); RecordImage( node->hwnd ); BlowupImage( node->hwnd, NULL ); InvalidateRect( node->viewhwnd, NULL, FALSE ); IEPrintAmtText( message, ImgedConfigInfo.shift ); } /* ShiftImage */
BBitmap* OilManipulator::ManipulateBitmap(BBitmap *original,Selection *selection,BStatusBar *status_bar) { BWindow *status_bar_window = NULL; if (status_bar != NULL) status_bar_window = status_bar->Window(); BRect a_rect = original->Bounds(); BBitmap *spare_buffer = DuplicateBitmap(original); BitmapDrawer *target = new BitmapDrawer(original); BitmapDrawer *source = new BitmapDrawer(spare_buffer); int32 width = original->Bounds().Width() + 1; int32 height = original->Bounds().Height() + 1; float status_bar_update_step = 100.0 / (width*height) * 1000.0; BMessage progress_message = BMessage(B_UPDATE_STATUS_BAR); progress_message.AddFloat("delta",0.0); // We must select all pixels between 0 and width*height in a // pseudo-random order. int32 *offsets = new int32[width*height]; for (int32 i=0;i<width*height;i++) offsets[i] = i; /* We copy each pixel with the following pattern: O OOO X -> OXOO O */ int32 size_of_area = width*height-1; int32 width_times_height = width*height; uint32 moved_pixel; union { uint8 bytes[4]; uint32 word; } color; int32 random_array_size = 32; int32 *random_array = new int32[random_array_size]; for (int32 i=0;i<random_array_size;i++) { random_array[i] = random()%10 * (random()%2 == 0?-1:1); } if ((selection == NULL) || (selection->IsEmpty() == TRUE)) { // for (int32 i=0;i<width_times_height;i++) { while (size_of_area > 0) { // Select one pixel at random int32 new_offset = rand() % size_of_area; int32 spare = offsets[new_offset]; offsets[new_offset] = offsets[size_of_area]; size_of_area--; int32 x = spare % width; int32 y = spare / width; color.word = source->GetPixel(BPoint(x,y)); // randomize the color a bit color.bytes[0] = min_c(255,max_c(0,(int32)color.bytes[0] + random_array[size_of_area%random_array_size])); color.bytes[1] = min_c(255,max_c(0,(int32)color.bytes[1] + random_array[size_of_area%random_array_size])); color.bytes[2] = min_c(255,max_c(0,(int32)color.bytes[2] + random_array[size_of_area%random_array_size])); moved_pixel = color.word; target->SetPixel(BPoint(x-2,y-1),moved_pixel); target->SetPixel(BPoint(x-1,y-1),moved_pixel); target->SetPixel(BPoint(x,y-1),moved_pixel); target->SetPixel(BPoint(x-1,y-2),moved_pixel); target->SetPixel(BPoint(x-1,y),moved_pixel); target->SetPixel(BPoint(x,y),moved_pixel); target->SetPixel(BPoint(x+1,y),moved_pixel); target->SetPixel(BPoint(x+2,y),moved_pixel); target->SetPixel(BPoint(x,y+1),moved_pixel); if (((size_of_area % 1000) == 0) && (status_bar != NULL) && (status_bar_window != NULL) && (status_bar_window->LockWithTimeout(0) == B_OK)) { status_bar->Update(status_bar_update_step); status_bar_window->Unlock(); } } } else { while (size_of_area > 0) { // Select one pixel at random int32 new_offset = rand() % size_of_area; int32 spare = offsets[new_offset]; offsets[new_offset] = offsets[size_of_area]; size_of_area--; int32 x = spare % width; int32 y = spare / width; color.word = source->GetPixel(BPoint(x,y)); // randomize the color a bit color.bytes[0] = min_c(255,max_c(0,(int32)color.bytes[0] + random_array[size_of_area%random_array_size])); color.bytes[1] = min_c(255,max_c(0,(int32)color.bytes[1] + random_array[size_of_area%random_array_size])); color.bytes[2] = min_c(255,max_c(0,(int32)color.bytes[2] + random_array[size_of_area%random_array_size])); moved_pixel = color.word; target->SetPixel(BPoint(x-2,y-1),moved_pixel,selection); target->SetPixel(BPoint(x-1,y-1),moved_pixel,selection); target->SetPixel(BPoint(x,y-1),moved_pixel,selection); target->SetPixel(BPoint(x-1,y-2),moved_pixel,selection); target->SetPixel(BPoint(x-1,y),moved_pixel,selection); target->SetPixel(BPoint(x,y),moved_pixel,selection); target->SetPixel(BPoint(x+1,y),moved_pixel,selection); target->SetPixel(BPoint(x+2,y),moved_pixel,selection); target->SetPixel(BPoint(x,y+1),moved_pixel,selection); if (((size_of_area % 1000) == 0) && (status_bar != NULL) && (status_bar_window != NULL) && (status_bar_window->LockWithTimeout(0) == B_OK)) { status_bar->Update(status_bar_update_step); status_bar_window->Unlock(); } } } // we should also delete the spare-bitmap delete spare_buffer; delete target; delete source; delete[] offsets; return original; }
/* * PasteImage - paste the image in the clipboard at the current point * - first check to see if the image was cut/copied from our program * - if it was, then we use the hXorClipped and hAndClipped bitmaps * we created in order to preserve the screen colors if ther were used * - otherwise, just copy from the clipboard */ void PasteImage( WPI_POINT *pt, WPI_POINT pointsize, HWND hwnd ) { HBITMAP hbitmap; HBITMAP hbitmapdup; HBITMAP holddup; HBITMAP oldbitmap; HBITMAP oldbitmap2; WPI_PRES pres; WPI_PRES mempres; HDC memdc; WPI_PRES clippres; HDC clipdc; WPI_RECT client; WPI_POINT truept; short width; short height; short clipwidth; short clipheight; img_node *node; int fstretchbmp; int bm_width, bm_height; WPI_RECTDIM left; WPI_RECTDIM right; WPI_RECTDIM top; WPI_RECTDIM bottom; WPI_RECTDIM client_l; WPI_RECTDIM client_r; WPI_RECTDIM client_t; WPI_RECTDIM client_b; #ifdef __OS2_PM__ int src_y, dest_y; #endif if( fEnableCutCopy ) { _wpi_getwrectvalues( clipRect.rect, &left, &top, &right, &bottom ); truept.x = left; truept.y = top; fstretchbmp = StretchPastedImage(); } else { truept.x = pt->x / pointsize.x; truept.y = pt->y / pointsize.y; fstretchbmp = -1; } node = SelectImage( hwnd ); pres = _wpi_getpres( node->viewhwnd ); if( _wpi_getclipboardowner( Instance ) == HMainWindow && node->imgtype != BITMAP_IMG ) { _wpi_getbitmapdim( hAndClipped, &bm_width, &bm_height ); GetClientRect( node->hwnd, &client ); if( fEnableCutCopy ) { width = (short)_wpi_getwidthrect( clipRect.rect ); height = (short)_wpi_getheightrect( clipRect.rect ); } else { _wpi_getrectvalues( client, &client_l, &client_t, &client_r, &client_b ); width = (short)( client_r / pointsize.x - truept.x ); if( width > (short)bm_width ) width = (short)bm_width; height = (short)( client_b / pointsize.y - truept.y ); if( height > (short)bm_height ) { height = (short)bm_height; } } mempres = _wpi_createcompatiblepres( pres, Instance, &memdc ); _wpi_setstretchbltmode( mempres, COLORONCOLOR ); clippres = _wpi_createcompatiblepres( pres, Instance, &clipdc ); oldbitmap = _wpi_selectbitmap( mempres, node->handbitmap ); oldbitmap2 = _wpi_selectbitmap( clippres, hAndClipped ); if( fstretchbmp == FALSE ) { clipwidth = (short)bm_width; if( clipwidth > (short)width ) clipwidth = (short)width; clipheight = (short)bm_height; if( clipheight > (short)height ) clipheight = (short)height; _wpi_patblt( mempres, truept.x, truept.y, width, height, BLACKNESS ); _wpi_bitblt( mempres, truept.x, truept.y, clipwidth, clipheight, clippres, 0, 0, SRCCOPY ); } else if( fstretchbmp == TRUE ) { _wpi_stretchblt( mempres, truept.x, truept.y, width, height, clippres, 0, 0, bm_width, bm_height, SRCCOPY); } else { _wpi_bitblt( mempres, truept.x, truept.y, width, height, clippres, 0, 0, SRCCOPY ); } _wpi_getoldbitmap( mempres, oldbitmap ); oldbitmap = _wpi_selectbitmap( mempres, node->hxorbitmap ); hbitmapdup = DuplicateBitmap( hXorClipped ); _wpi_getoldbitmap( clippres, oldbitmap2 ); oldbitmap2 = _wpi_selectbitmap( clippres, hbitmapdup ); if( fstretchbmp == FALSE ) { clipwidth = (short)bm_width; if( clipwidth > (short)width ) clipwidth = (short)width; clipheight = (short)bm_height; if( clipheight > (short)height ) clipheight = (short)height; _wpi_patblt( mempres, truept.x, truept.y, width, height, WHITENESS ); #ifdef __OS2_PM__ if( bm_height > height ) { src_y = bm_height - height; dest_y = truept.y; } else { src_y = 0; dest_y = truept.y + (height - bm_height); } _wpi_bitblt( mempres, truept.x, dest_y, clipwidth, clipheight, clippres, 0, src_y, SRCCOPY ); #else _wpi_bitblt( mempres, truept.x, truept.y, clipwidth, clipheight, clippres, 0, 0, SRCCOPY ); #endif } else if( fstretchbmp == TRUE ) { _wpi_stretchblt( mempres, truept.x, truept.y, width, height, clippres, 0, 0, bm_width, bm_height, SRCCOPY ); } else { _wpi_bitblt( mempres, truept.x, truept.y, width, height, clippres, 0, 0, SRCCOPY ); } _wpi_getoldbitmap( mempres, oldbitmap ); _wpi_getoldbitmap( clippres, oldbitmap2 ); _wpi_deletebitmap( hbitmapdup ); _wpi_deletecompatiblepres( mempres, memdc ); _wpi_deletecompatiblepres( clippres, clipdc ); } else { if( node->imgtype != BITMAP_IMG ) { CleanupClipboard(); } _wpi_openclipboard( Instance, HMainWindow ); hbitmap = _wpi_getclipboarddata( Instance, CF_BITMAP ); hbitmapdup = DuplicateBitmap( hbitmap ); _wpi_closeclipboard( Instance ); _wpi_getbitmapdim( hbitmapdup, &bm_width, &bm_height ); GetClientRect( node->hwnd, &client ); if( fEnableCutCopy ) { width = (short)_wpi_getwidthrect( clipRect.rect ); height = (short)_wpi_getheightrect( clipRect.rect ); } else { _wpi_getrectvalues( client, &client_l, &client_t, &client_r, &client_b ); width = (short)( client_r / pointsize.x - truept.x ); if( width > (short)bm_width ) width = (short)bm_width; height = (short)( client_b / pointsize.y - truept.y ); if( height > (short)bm_height ) { height = (short)bm_height; } } clippres = _wpi_createcompatiblepres( pres, Instance, &clipdc ); mempres = _wpi_createcompatiblepres( pres, Instance, &memdc ); _wpi_setstretchbltmode( mempres, COLORONCOLOR ); holddup = _wpi_selectbitmap( clippres, hbitmapdup ); oldbitmap = _wpi_selectbitmap( mempres, node->hxorbitmap ); if( fstretchbmp == FALSE ) { clipwidth = (short)bm_width; if( clipwidth > (short)width ) clipwidth = (short)width; clipheight = (short)bm_height; if( clipheight > (short)height ) clipheight = (short)height; _wpi_patblt( mempres, truept.x, truept.y, width, height, WHITENESS ); #ifdef __OS2_PM__ if( bm_height > height ) { src_y = bm_height - height; dest_y = truept.y; } else { src_y = 0; dest_y = truept.y + (height - bm_height); } _wpi_bitblt( mempres, truept.x, dest_y, clipwidth, clipheight, clippres, 0, src_y, SRCCOPY ); #else _wpi_bitblt( mempres, truept.x, truept.y, clipwidth, clipheight, clippres, 0, 0, SRCCOPY ); #endif } else if( fstretchbmp == TRUE ) { _wpi_stretchblt( mempres, truept.x, truept.y, width, height, clippres, 0, 0, bm_width, bm_height, SRCCOPY ); } else { _wpi_bitblt( mempres, truept.x, truept.y, width, height, clippres, 0, 0, SRCCOPY ); } _wpi_getoldbitmap( clippres, holddup ); _wpi_deletebitmap( hbitmapdup ); _wpi_deletecompatiblepres( clippres, clipdc ); _wpi_getoldbitmap( mempres, oldbitmap ); oldbitmap = _wpi_selectbitmap( mempres, node->handbitmap ); _wpi_patblt( mempres, truept.x, truept.y, width, height, BLACKNESS ); _wpi_getoldbitmap( mempres, oldbitmap ); _wpi_deletecompatiblepres( mempres, memdc ); } ReleaseCapture(); _wpi_releasepres( node->viewhwnd, pres ); InvalidateRect( node->viewhwnd, NULL, TRUE ); if( !fEnableCutCopy ) { _wpi_setcursor( prevCursor ); _wpi_destroycursor( pointCursor ); SetToolType( prevToolType ); } fEnableCutCopy = FALSE; RecordImage( hwnd ); BlowupImage( NULL, NULL ); PrintHintTextByID( WIE_BITMAPPASTED, NULL ); } /* PasteImage */
BBitmap* ColorBalanceManipulator::ManipulateBitmap(ManipulatorSettings *set,BBitmap *original,Selection *selection,BStatusBar *status_bar) { ColorBalanceManipulatorSettings *new_settings = dynamic_cast<ColorBalanceManipulatorSettings*>(set); if (new_settings == NULL) return NULL; if (original == NULL) return NULL; if ((new_settings->red_difference == 0) &&(new_settings->green_difference == 0) && (new_settings->blue_difference == 0)) return NULL; BBitmap *source_bitmap; BBitmap *target_bitmap; BBitmap *new_bitmap = NULL; if (original == preview_bitmap) { target_bitmap = original; source_bitmap = copy_of_the_preview_bitmap; } else { target_bitmap = original; new_bitmap = DuplicateBitmap(original,0); source_bitmap = new_bitmap; } uint32 *source_bits = (uint32*)source_bitmap->Bits(); uint32 *target_bits = (uint32*)target_bitmap->Bits(); int32 source_bpr = source_bitmap->BytesPerRow()/4; int32 target_bpr = target_bitmap->BytesPerRow()/4; int32 left = target_bitmap->Bounds().left; int32 right = target_bitmap->Bounds().right; int32 top = target_bitmap->Bounds().top; int32 bottom = target_bitmap->Bounds().bottom; union { uint8 bytes[4]; uint32 word; } color; if (selection->IsEmpty() == TRUE) { for (int32 y=top;y<=bottom;y++) { for (int32 x=left;x<=right;x++) { color.word = *source_bits++; color.bytes[0] = max_c(min_c(255,color.bytes[0]+new_settings->blue_difference),0); color.bytes[1] = max_c(min_c(255,color.bytes[1]+new_settings->green_difference),0); color.bytes[2] = max_c(min_c(255,color.bytes[2]+new_settings->red_difference),0); *target_bits++ = color.word; } } } else { for (int32 y=top;y<=bottom;y++) { for (int32 x=left;x<=right;x++) { if (selection->ContainsPoint(x,y)) { color.word = *source_bits++; color.bytes[0] = max_c(min_c(255,color.bytes[0]+new_settings->blue_difference),0); color.bytes[1] = max_c(min_c(255,color.bytes[1]+new_settings->green_difference),0); color.bytes[2] = max_c(min_c(255,color.bytes[2]+new_settings->red_difference),0); *target_bits++ = color.word; } else { *target_bits++ = *source_bits++; } } } } if (new_bitmap != NULL) { delete new_bitmap; } return original; }