mirror of https://github.com/GNOME/gimp.git
694 lines
18 KiB
C
694 lines
18 KiB
C
/*
|
|
* WinClipboard Win32 Windoze Copy&Paste Plug-in
|
|
* Copyright (C) 1999 Hans Breuer
|
|
* Hans Breuer, Hans@Breuer.org
|
|
* 08/07/99
|
|
*
|
|
* 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 of the License, 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 program; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
*
|
|
* Based on (at least) the following plug-ins:
|
|
* Header
|
|
* WinSnap
|
|
*
|
|
* Any suggestions, bug-reports or patches are welcome.
|
|
*/
|
|
|
|
#include "config.h"
|
|
|
|
#include <windows.h>
|
|
#include <stdlib.h>
|
|
|
|
#include <libgimp/gimp.h>
|
|
|
|
#include "libgimp/stdplugins-intl.h"
|
|
|
|
|
|
/* History:
|
|
*
|
|
* 08/07/99 Implementation and release.
|
|
* 08/10/99 Big speed increase by using gimp_tile_cache_size()
|
|
* Thanks to Kevin Turner's documentation at:
|
|
* http://www.poboxes.com/kevint/gimp/doc/plugin-doc-2.1.html
|
|
*
|
|
* TODO (maybe):
|
|
*
|
|
* - Support for 4,2,1 bit bitmaps
|
|
* - Unsupported formats could be delegated to GIMP Loader (e.g. wmf)
|
|
* - ...
|
|
*/
|
|
|
|
/* How many steps the progress control should do
|
|
*/
|
|
#define PROGRESS_STEPS 25
|
|
#define StepProgress(one,all) \
|
|
(0 == (one % ((all / PROGRESS_STEPS)+1)))
|
|
|
|
/* FIXME: I'll use -1 as IMAGE_NONE. Is it correct ???
|
|
*/
|
|
#define IMAGE_NONE -1
|
|
|
|
/* Declare some local functions.
|
|
*/
|
|
static void query (void);
|
|
static void run (const gchar *name,
|
|
gint nparams,
|
|
const GimpParam *param,
|
|
gint *nreturn_vals,
|
|
GimpParam **return_vals);
|
|
|
|
/* Plugin function prototypes
|
|
*/
|
|
static int CB_CopyImage (gboolean interactive,
|
|
gint32 image_ID,
|
|
gint32 drawable_ID);
|
|
|
|
static int CB_PasteImage (gboolean interactive,
|
|
gint32 image_ID,
|
|
gint32 drawable_ID);
|
|
|
|
|
|
GimpPlugInInfo PLUG_IN_INFO =
|
|
{
|
|
NULL, /* init_proc */
|
|
NULL, /* quit_proc */
|
|
query, /* query_proc */
|
|
run, /* run_proc */
|
|
};
|
|
|
|
|
|
MAIN ()
|
|
|
|
static void
|
|
query ()
|
|
{
|
|
static GimpParamDef copy_args[] =
|
|
{
|
|
{ GIMP_PDB_INT32, "run_mode", "Interactive, non-interactive" },
|
|
{ GIMP_PDB_IMAGE, "image", "Input image" },
|
|
{ GIMP_PDB_DRAWABLE, "drawable", "Drawable to save" }
|
|
};
|
|
|
|
gimp_install_procedure ("plug_in_clipboard_copy",
|
|
"copy image to clipboard",
|
|
"Copies the active drawable to the clipboard.",
|
|
"Hans Breuer",
|
|
"Hans Breuer",
|
|
"1999",
|
|
N_("<Image>/Edit/Copy to Clipboard"),
|
|
"INDEXED*, RGB*",
|
|
GIMP_PLUGIN,
|
|
G_N_ELEMENTS (copy_args), 0,
|
|
copy_args, NULL);
|
|
|
|
gimp_install_procedure ("plug_in_clipboard_paste",
|
|
"paste image from clipboard",
|
|
"Paste image from clipboard into active image.",
|
|
"Hans Breuer",
|
|
"Hans Breuer",
|
|
"1999",
|
|
N_("<Image>/Edit/Paste from Clipboard"),
|
|
"INDEXED*, RGB*",
|
|
GIMP_PLUGIN,
|
|
G_N_ELEMENTS (copy_args), 0,
|
|
copy_args, NULL);
|
|
|
|
gimp_install_procedure ("plug_in_clipboard_paste_as_new",
|
|
"Get image from clipboard",
|
|
"Get an image from the Windows clipboard, creating a new image",
|
|
"Hans Breuer",
|
|
"Hans Breuer",
|
|
"1999",
|
|
N_("<Toolbox>/File/Acquire/From Clipboard"),
|
|
"",
|
|
GIMP_PLUGIN,
|
|
1, 0,
|
|
copy_args, NULL);
|
|
|
|
}
|
|
|
|
static void
|
|
run (const gchar *name,
|
|
gint nparams,
|
|
const GimpParam *param,
|
|
gint *nreturn_vals,
|
|
GimpParam **return_vals)
|
|
{
|
|
static GimpParam values[2];
|
|
GimpRunMode run_mode;
|
|
|
|
run_mode = param[0].data.d_int32;
|
|
|
|
*nreturn_vals = 1;
|
|
*return_vals = values;
|
|
values[0].type = GIMP_PDB_STATUS;
|
|
values[0].data.d_status = GIMP_PDB_CALLING_ERROR;
|
|
|
|
INIT_I18N();
|
|
|
|
if (strcmp (name, "plug_in_clipboard_copy") == 0)
|
|
{
|
|
*nreturn_vals = 1;
|
|
if (CB_CopyImage (GIMP_RUN_INTERACTIVE==run_mode,
|
|
param[1].data.d_int32,
|
|
param[2].data.d_int32))
|
|
values[0].data.d_status = GIMP_PDB_SUCCESS;
|
|
else
|
|
values[0].data.d_status = GIMP_PDB_EXECUTION_ERROR;
|
|
}
|
|
else if (strcmp (name, "plug_in_clipboard_paste") == 0)
|
|
{
|
|
*nreturn_vals = 1;
|
|
if (CB_PasteImage (GIMP_RUN_INTERACTIVE==run_mode,
|
|
param[1].data.d_int32,
|
|
param[2].data.d_int32))
|
|
values[0].data.d_status = GIMP_PDB_SUCCESS;
|
|
else
|
|
values[0].data.d_status = GIMP_PDB_EXECUTION_ERROR;
|
|
}
|
|
else if (strcmp (name, "plug_in_clipboard_paste_as_new") == 0)
|
|
{
|
|
*nreturn_vals = 1;
|
|
if (CB_PasteImage (GIMP_RUN_INTERACTIVE==run_mode,
|
|
IMAGE_NONE,
|
|
IMAGE_NONE))
|
|
values[0].data.d_status = GIMP_PDB_SUCCESS;
|
|
else
|
|
values[0].data.d_status = GIMP_PDB_EXECUTION_ERROR;
|
|
}
|
|
}
|
|
|
|
/* Plugin Function implementation
|
|
*/
|
|
static int
|
|
CB_CopyImage (gboolean interactive,
|
|
gint32 image_ID,
|
|
gint32 drawable_ID)
|
|
{
|
|
GimpDrawable *drawable;
|
|
GimpImageType drawable_type;
|
|
GimpPixelRgn pixel_rgn;
|
|
gchar *sStatus = NULL;
|
|
|
|
int nSizeDIB=0;
|
|
int nSizePal=0;
|
|
int nSizeLine=0; /* DIB lines are 32 bit aligned */
|
|
|
|
HANDLE hDIB;
|
|
BOOL bRet;
|
|
|
|
drawable = gimp_drawable_get (drawable_ID);
|
|
drawable_type = gimp_drawable_type (drawable_ID);
|
|
gimp_pixel_rgn_init (&pixel_rgn, drawable, 0, 0, drawable->width, drawable->height, FALSE, FALSE);
|
|
|
|
/* allocate room for DIB */
|
|
if (GIMP_INDEXED_IMAGE == drawable_type)
|
|
{
|
|
nSizeLine = ((drawable->width-1)/4+1)*4;
|
|
nSizeDIB = sizeof(RGBQUAD) * 256 /* always full color map size */
|
|
+ nSizeLine * drawable->height
|
|
+ sizeof (BITMAPINFOHEADER);
|
|
}
|
|
else
|
|
{
|
|
nSizeLine = ((drawable->width*3-1)/4+1)*4;
|
|
nSizeDIB = nSizeLine * drawable->height
|
|
+ sizeof (BITMAPINFOHEADER);
|
|
}
|
|
|
|
hDIB = GlobalAlloc (GMEM_MOVEABLE | GMEM_DDESHARE, nSizeDIB);
|
|
if (NULL == hDIB)
|
|
{
|
|
g_message ("Failed to allocate DIB");
|
|
bRet = FALSE;
|
|
}
|
|
|
|
/* fill header info */
|
|
if (bRet)
|
|
{
|
|
BITMAPINFOHEADER *pInfo;
|
|
|
|
bRet = FALSE;
|
|
pInfo = GlobalLock (hDIB);
|
|
if (pInfo)
|
|
{
|
|
pInfo->biSize = sizeof(BITMAPINFOHEADER);
|
|
pInfo->biWidth = drawable->width;
|
|
pInfo->biHeight = drawable->height;
|
|
pInfo->biPlanes = 1;
|
|
pInfo->biBitCount = (GIMP_INDEXED_IMAGE == drawable_type ? 8 : 24);
|
|
pInfo->biCompression = BI_RGB; /* none */
|
|
pInfo->biSizeImage = 0; /* not calculated/needed */
|
|
pInfo->biXPelsPerMeter =
|
|
pInfo->biYPelsPerMeter = 0;
|
|
/* color map size */
|
|
pInfo->biClrUsed = (GIMP_INDEXED_IMAGE == drawable_type ? 256 : 0);
|
|
pInfo->biClrImportant = 0; /* all */
|
|
|
|
GlobalUnlock (hDIB);
|
|
bRet = TRUE;
|
|
} /* (pInfo) */
|
|
else
|
|
g_message("Failed to lock DIB Header");
|
|
}
|
|
|
|
/* fill color map */
|
|
if (bRet && (GIMP_INDEXED_IMAGE == drawable_type))
|
|
{
|
|
char *pBmp;
|
|
|
|
bRet = FALSE;
|
|
pBmp = GlobalLock (hDIB);
|
|
if (pBmp)
|
|
{
|
|
RGBQUAD *pPal;
|
|
int nColors;
|
|
unsigned char *cmap;
|
|
pPal = (RGBQUAD*)(pBmp + sizeof(BITMAPINFOHEADER));
|
|
nSizePal = sizeof(RGBQUAD) * 256;
|
|
|
|
/* get the gimp colormap */
|
|
cmap = gimp_image_get_cmap (image_ID, &nColors);
|
|
|
|
if (cmap)
|
|
{
|
|
int i;
|
|
for (i = 0; (i < 256) && (i < nColors); i++)
|
|
{
|
|
pPal[i].rgbReserved = 0; /* is this alpha? */
|
|
pPal[i].rgbRed = cmap[3*i];
|
|
pPal[i].rgbGreen = cmap[3*i+1];
|
|
pPal[i].rgbBlue = cmap[3*i+2];
|
|
}
|
|
|
|
g_free(cmap);
|
|
bRet = TRUE;
|
|
} /* (cmap) */
|
|
else
|
|
g_message ("Can't get color map");
|
|
GlobalUnlock (hDIB);
|
|
} /* (pBmp) */
|
|
else
|
|
g_message ("Failed to lock DIB Palette");
|
|
} /* indexed */
|
|
|
|
/* following the slow part ... */
|
|
if (interactive)
|
|
gimp_progress_init (_("Copying..."));
|
|
|
|
/* speed it up with: */
|
|
gimp_tile_cache_size (drawable->width * gimp_tile_height () * drawable->bpp);
|
|
|
|
/* copy data to DIB */
|
|
if (bRet)
|
|
{
|
|
unsigned char *pData;
|
|
|
|
bRet = FALSE;
|
|
pData = GlobalLock (hDIB);
|
|
|
|
if (pData)
|
|
{
|
|
unsigned char *pLine;
|
|
|
|
/* calculate real offset */
|
|
pData += (sizeof(BITMAPINFOHEADER) + nSizePal);
|
|
|
|
pLine = g_new (guchar, drawable->width * drawable->bpp);
|
|
|
|
if (GIMP_INDEXED_IMAGE == drawable_type)
|
|
{
|
|
int x, y;
|
|
for (y = 0; y < drawable->height; y++)
|
|
{
|
|
if ((interactive) && (StepProgress(y,drawable->height)))
|
|
gimp_progress_update ((double)y / drawable->height);
|
|
|
|
gimp_pixel_rgn_get_row (&pixel_rgn, pLine, 0,
|
|
drawable->height-y-1, /* invert it */
|
|
drawable->width);
|
|
for (x = 0; x < drawable->width; x++)
|
|
pData[x+y*nSizeLine] = pLine[x*drawable->bpp];
|
|
}
|
|
}
|
|
else
|
|
{
|
|
int x, y;
|
|
for (y = 0; y < drawable->height; y++)
|
|
{
|
|
if ((interactive) && (StepProgress(y,drawable->height)))
|
|
gimp_progress_update ((double)y / drawable->height);
|
|
|
|
gimp_pixel_rgn_get_row (&pixel_rgn, pLine, 0,
|
|
drawable->height-y-1, /* invert it */
|
|
drawable->width);
|
|
for (x = 0; x < drawable->width; x++)
|
|
{
|
|
/* RGBQUAD: blue, green, red, reserved */
|
|
pData[x*3+y*nSizeLine] = pLine[x*drawable->bpp+2]; /* blue */
|
|
pData[x*3+y*nSizeLine+1] = pLine[x*drawable->bpp+1]; /* green */
|
|
pData[x*3+y*nSizeLine+2] = pLine[x*drawable->bpp]; /* red */
|
|
/*pData[x+y*drawable->width*3+3] = 0;*/ /* reserved */
|
|
}
|
|
}
|
|
}
|
|
|
|
g_free (pLine);
|
|
bRet = TRUE;
|
|
|
|
GlobalUnlock (hDIB);
|
|
} /* (pData) */
|
|
else
|
|
g_message("Failed to lock DIB Data");
|
|
} /* copy data to DIB */
|
|
|
|
/* copy DIB to ClipBoard */
|
|
if (bRet)
|
|
{
|
|
if (!OpenClipboard (NULL))
|
|
{
|
|
g_message ("Cannot open the Clipboard!");
|
|
bRet = FALSE;
|
|
}
|
|
else
|
|
{
|
|
if (bRet && !EmptyClipboard ())
|
|
{
|
|
g_message ("Cannot empty the Clipboard");
|
|
bRet = FALSE;
|
|
}
|
|
if (bRet)
|
|
{
|
|
if (NULL != SetClipboardData (CF_DIB, hDIB))
|
|
hDIB = NULL; /* data now owned by clipboard */
|
|
else
|
|
g_message ("Failed to set clipboard data ");
|
|
}
|
|
|
|
if (!CloseClipboard ())
|
|
g_message ("Failed to close Clipboard");
|
|
}
|
|
}
|
|
/* done */
|
|
if (hDIB)
|
|
GlobalFree(hDIB);
|
|
|
|
gimp_drawable_detach (drawable);
|
|
|
|
return bRet;
|
|
} /* CB_CopyImage */
|
|
|
|
static void
|
|
decompose_mask (guint32 mask,
|
|
gint *shift,
|
|
gint *prec)
|
|
{
|
|
*shift = 0;
|
|
*prec = 0;
|
|
|
|
while (!(mask & 0x1))
|
|
{
|
|
(*shift)++;
|
|
mask >>= 1;
|
|
}
|
|
|
|
while (mask & 0x1)
|
|
{
|
|
(*prec)++;
|
|
mask >>= 1;
|
|
}
|
|
}
|
|
|
|
static int
|
|
CB_PasteImage (gboolean interactive,
|
|
gint32 image_ID,
|
|
gint32 drawable_ID)
|
|
{
|
|
UINT fmt;
|
|
BOOL bRet=TRUE;
|
|
HANDLE hDIB;
|
|
BITMAPINFO *pInfo;
|
|
gint32 nWidth = 0;
|
|
gint32 nHeight = 0;
|
|
gint32 nBitsPS = 0;
|
|
gint32 nColors = 0;
|
|
guint32 maskR;
|
|
guint32 maskG;
|
|
guint32 maskB;
|
|
gint shiftR;
|
|
gint shiftG;
|
|
gint shiftB;
|
|
gint precR;
|
|
gint precG;
|
|
gint precB;
|
|
gint maxR;
|
|
gint maxG;
|
|
gint maxB;
|
|
|
|
if (!OpenClipboard (NULL))
|
|
{
|
|
g_message("Failed to open clipboard");
|
|
return FALSE;
|
|
}
|
|
|
|
fmt = EnumClipboardFormats (0);
|
|
while ((CF_BITMAP != fmt) && (CF_DIB != fmt) && (0 != fmt))
|
|
fmt = EnumClipboardFormats (fmt);
|
|
|
|
if (0 == fmt)
|
|
{
|
|
g_message (_("Unsupported format or Clipboard empty!"));
|
|
bRet = FALSE;
|
|
}
|
|
|
|
/* there is something supported */
|
|
if (bRet)
|
|
{
|
|
hDIB = GetClipboardData (CF_DIB);
|
|
|
|
if (NULL == hDIB)
|
|
{
|
|
g_message (_("Can't get Clipboard data."));
|
|
bRet = FALSE;
|
|
}
|
|
}
|
|
|
|
/* read header */
|
|
if (bRet && hDIB)
|
|
{
|
|
pInfo = GlobalLock (hDIB);
|
|
if (NULL == pInfo)
|
|
{
|
|
g_message ("Can't lock Clipboard data!");
|
|
bRet = FALSE;
|
|
}
|
|
|
|
if (bRet && pInfo->bmiHeader.biCompression == BI_BITFIELDS)
|
|
{
|
|
maskR = ((DWORD *)pInfo->bmiColors)[0];
|
|
maskG = ((DWORD *)pInfo->bmiColors)[1];
|
|
maskB = ((DWORD *)pInfo->bmiColors)[2];
|
|
decompose_mask (maskR, &shiftR, &precR);
|
|
maxR = (1 << precR) - 1;
|
|
decompose_mask (maskG, &shiftG, &precG);
|
|
maxG = (1 << precG) - 1;
|
|
decompose_mask (maskB, &shiftB, &precB);
|
|
maxB = (1 << precB) - 1;
|
|
}
|
|
|
|
if ((bRet) &&
|
|
((pInfo->bmiHeader.biSize != sizeof(BITMAPINFOHEADER)
|
|
|| (pInfo->bmiHeader.biCompression != BI_RGB
|
|
&& pInfo->bmiHeader.biCompression != BI_BITFIELDS))))
|
|
{
|
|
g_message ("Unsupported bitmap format (%d)!",
|
|
pInfo->bmiHeader.biCompression);
|
|
bRet = FALSE;
|
|
}
|
|
|
|
if (bRet && pInfo)
|
|
{
|
|
nWidth = pInfo->bmiHeader.biWidth;
|
|
nHeight = pInfo->bmiHeader.biHeight;
|
|
nBitsPS = pInfo->bmiHeader.biBitCount;
|
|
nColors = pInfo->bmiHeader.biClrUsed;
|
|
}
|
|
}
|
|
|
|
if ((0 != nWidth) && (0 != nHeight))
|
|
{
|
|
GimpDrawable *drawable;
|
|
GimpPixelRgn pixel_rgn;
|
|
guchar *pData;
|
|
GimpParam *params;
|
|
gint retval;
|
|
gboolean bIsNewImage = TRUE;
|
|
gint oldBPP = 0;
|
|
guchar *pLine;
|
|
RGBQUAD *pPal;
|
|
const int nSizeLine = ((nWidth*(nBitsPS/8)-1)/4+1)*4;
|
|
|
|
/* Check if clipboard data and existing image are compatible */
|
|
if (IMAGE_NONE != drawable_ID)
|
|
{
|
|
drawable = gimp_drawable_get (drawable_ID);
|
|
oldBPP = drawable->bpp;
|
|
gimp_drawable_detach (drawable);
|
|
}
|
|
|
|
if ((IMAGE_NONE == image_ID)
|
|
|| (3 != oldBPP) || (24 != nBitsPS))
|
|
{
|
|
/* create new image */
|
|
image_ID = gimp_image_new (nWidth, nHeight, nBitsPS <= 8 ? GIMP_INDEXED : GIMP_RGB);
|
|
gimp_image_undo_disable(image_ID);
|
|
drawable_ID = gimp_layer_new (image_ID, _("Background"), nWidth, nHeight,
|
|
nBitsPS <= 8 ? GIMP_INDEXED_IMAGE : GIMP_RGB_IMAGE,
|
|
100, GIMP_NORMAL_MODE);
|
|
}
|
|
else
|
|
{
|
|
/* ??? gimp_convert_rgb (image_ID);
|
|
*/
|
|
drawable_ID = gimp_layer_new (image_ID, _("Pasted"), nWidth, nHeight,
|
|
nBitsPS <= 8 ? GIMP_INDEXED_IMAGE : GIMP_RGB_IMAGE,
|
|
100, GIMP_NORMAL_MODE);
|
|
bIsNewImage = FALSE;
|
|
}
|
|
|
|
gimp_image_add_layer (image_ID, drawable_ID, -1);
|
|
drawable = gimp_drawable_get (drawable_ID);
|
|
|
|
gimp_pixel_rgn_init (&pixel_rgn, drawable, 0, 0, drawable->width, drawable->height, FALSE, FALSE);
|
|
|
|
/* following the slow part ... */
|
|
if (interactive)
|
|
gimp_progress_init (_("Pasting..."));
|
|
|
|
/* adjust pointer */
|
|
pPal = pInfo->bmiColors;
|
|
if (pInfo->bmiHeader.biCompression == BI_BITFIELDS)
|
|
pData = (guchar*)pPal + sizeof(DWORD) * 3;
|
|
else
|
|
pData = (guchar*)pPal + sizeof(RGBQUAD) * nColors;
|
|
|
|
/* create palette */
|
|
if (0 != nColors)
|
|
{
|
|
int c;
|
|
guchar *cmap;
|
|
|
|
cmap = g_new (guchar, nColors*3);
|
|
for (c = 0; c < nColors; c++)
|
|
{
|
|
cmap[c*3] = pPal[c].rgbRed;
|
|
cmap[c*3+1] = pPal[c].rgbGreen;
|
|
cmap[c*3+2] = pPal[c].rgbBlue;
|
|
}
|
|
gimp_image_set_cmap (image_ID, cmap, nColors);
|
|
g_free (cmap);
|
|
}
|
|
|
|
/* speed it up with: */
|
|
gimp_tile_cache_size (drawable->width * gimp_tile_height () * drawable->bpp );
|
|
|
|
/* change data format and copy data */
|
|
if ((24 == nBitsPS && pInfo->bmiHeader.biCompression == BI_RGB)
|
|
|| (pInfo->bmiHeader.biCompression == BI_BITFIELDS))
|
|
{
|
|
int y;
|
|
const int bps = nBitsPS / 8;
|
|
pLine = g_new (guchar, drawable->width*drawable->bpp);
|
|
|
|
for (y = 0; y < drawable->height; y++)
|
|
{
|
|
int x;
|
|
|
|
if ((interactive) && (StepProgress (y, drawable->height)))
|
|
gimp_progress_update ((double)y / drawable->height);
|
|
|
|
if (pInfo->bmiHeader.biCompression == BI_RGB)
|
|
for (x = 0; x < drawable->width; x++)
|
|
{
|
|
pLine[x*drawable->bpp] = pData[y*nSizeLine+x*bps+2];
|
|
pLine[x*drawable->bpp+1] = pData[y*nSizeLine+x*bps+1];
|
|
pLine[x*drawable->bpp+2] = pData[y*nSizeLine+x*bps];
|
|
}
|
|
else
|
|
for (x = 0; x < drawable->width; x++)
|
|
{
|
|
guint dw;
|
|
|
|
if (nBitsPS == 32)
|
|
dw = *((DWORD *)(pData + y*nSizeLine + x*4));
|
|
else
|
|
dw = *((WORD *)(pData + y*nSizeLine + x*2));
|
|
pLine[x*drawable->bpp] = (255 * ((dw & maskR) >> shiftR)) / maxR;
|
|
pLine[x*drawable->bpp+1] = (255 * ((dw & maskG) >> shiftG)) / maxG;
|
|
pLine[x*drawable->bpp+2] = (255 * ((dw & maskB) >> shiftB)) / maxB;
|
|
}
|
|
|
|
/* copy data to GIMP */
|
|
gimp_pixel_rgn_set_rect (&pixel_rgn, pLine, 0, drawable->height-1-y, drawable->width, 1);
|
|
}
|
|
g_free (pLine);
|
|
}
|
|
else if (8 == nBitsPS)
|
|
{
|
|
int y;
|
|
/* copy line by line */
|
|
for (y = 0; y < drawable->height; y++)
|
|
{
|
|
if ((interactive) && (StepProgress (y, drawable->height)))
|
|
gimp_progress_update ((double)y / drawable->height);
|
|
|
|
pLine = pData + y*nSizeLine; /* adjust pointer */
|
|
gimp_pixel_rgn_set_row (&pixel_rgn, pLine, 0, drawable->height-1-y, drawable->width);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/* copy and shift bits */
|
|
g_message ("%d bits per sample not yet supported!", nBitsPS);
|
|
}
|
|
|
|
gimp_drawable_flush (drawable);
|
|
gimp_drawable_detach (drawable);
|
|
|
|
/* Don't forget to display the new image! */
|
|
if (bIsNewImage)
|
|
gimp_display_new (image_ID);
|
|
else
|
|
{
|
|
gimp_layer_set_visible (drawable_ID, TRUE);
|
|
gimp_displays_flush ();
|
|
}
|
|
}
|
|
|
|
/* done */
|
|
/* clear clipboard? */
|
|
if (NULL != hDIB)
|
|
{
|
|
GlobalUnlock (pInfo);
|
|
GlobalFree (hDIB);
|
|
}
|
|
|
|
CloseClipboard ();
|
|
|
|
/* shouldn't this be done by caller?? */
|
|
gimp_image_undo_enable (image_ID);
|
|
|
|
return bRet;
|
|
} /* CB_PasteImage */
|