plug-ins/bmp/bmp.[ch] plug-ins/bmp/bmpread.c return STATUS_CANCEL if
2000-02-12 Michael Natterer <mitch@gimp.org> * plug-ins/bmp/bmp.[ch] * plug-ins/bmp/bmpread.c * plug-ins/bmp/bmpwrite.c: return STATUS_CANCEL if "Cancel" was pressed, code & ui cleanups.
This commit is contained in:

committed by
Michael Natterer

parent
80acd3bf67
commit
6ff6f358d9
@ -1,3 +1,10 @@
|
||||
2000-02-12 Michael Natterer <mitch@gimp.org>
|
||||
|
||||
* plug-ins/bmp/bmp.[ch]
|
||||
* plug-ins/bmp/bmpread.c
|
||||
* plug-ins/bmp/bmpwrite.c: return STATUS_CANCEL if "Cancel" was
|
||||
pressed, code & ui cleanups.
|
||||
|
||||
Sat Feb 12 16:02:12 CET 2000 Sven Neumann <sven@gimp.org>
|
||||
|
||||
* app/menus.c: ooops, must have been late
|
||||
|
@ -259,10 +259,7 @@ run (gchar *name,
|
||||
|
||||
if (status == STATUS_SUCCESS)
|
||||
{
|
||||
if (! WriteBMP (param[3].data.d_string, image_ID, drawable_ID))
|
||||
{
|
||||
status = STATUS_EXECUTION_ERROR;
|
||||
}
|
||||
status = WriteBMP (param[3].data.d_string, image_ID, drawable_ID);
|
||||
}
|
||||
|
||||
if (export == EXPORT_EXPORT)
|
||||
@ -292,18 +289,18 @@ void
|
||||
FromL (gint32 wert,
|
||||
guchar *bopuffer)
|
||||
{
|
||||
bopuffer[0]=(wert & 0x000000ff)>>0x00;
|
||||
bopuffer[1]=(wert & 0x0000ff00)>>0x08;
|
||||
bopuffer[2]=(wert & 0x00ff0000)>>0x10;
|
||||
bopuffer[3]=(wert & 0xff000000)>>0x18;
|
||||
bopuffer[0] = (wert & 0x000000ff)>>0x00;
|
||||
bopuffer[1] = (wert & 0x0000ff00)>>0x08;
|
||||
bopuffer[2] = (wert & 0x00ff0000)>>0x10;
|
||||
bopuffer[3] = (wert & 0xff000000)>>0x18;
|
||||
}
|
||||
|
||||
void
|
||||
FromS (gint16 wert,
|
||||
guchar *bopuffer)
|
||||
{
|
||||
bopuffer[0]=(wert & 0x00ff)>>0x00;
|
||||
bopuffer[1]=(wert & 0xff00)>>0x08;
|
||||
bopuffer[0] = (wert & 0x00ff)>>0x00;
|
||||
bopuffer[1] = (wert & 0xff00)>>0x08;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -319,5 +316,3 @@ init_gtk (void)
|
||||
gtk_init (&argc, &argv);
|
||||
gtk_rc_parse (gimp_gtkrc ());
|
||||
}
|
||||
|
||||
|
||||
|
@ -9,50 +9,78 @@
|
||||
#define Write(file,buffer,len) fwrite(buffer, len, 1, file)
|
||||
#define WriteOK(file,buffer,len) (Write(buffer, len, file) != 0)
|
||||
|
||||
extern gint32 ToL(guchar *);
|
||||
extern void FromL(gint32, guchar *);
|
||||
extern gint16 ToS(guchar *);
|
||||
extern void FromS(gint16, guchar *);
|
||||
extern gint32 ReadBMP (char *);
|
||||
extern gint WriteBMP (char *,gint32,gint32);
|
||||
extern gint ReadColorMap(FILE *, unsigned char[256][3], int, int, int *);
|
||||
extern Image ReadImage(FILE *, int, int, unsigned char[256][3], int, int, int, int, int);
|
||||
extern void WriteColorMap(FILE *, int *, int *, int *, int);
|
||||
extern void WriteImage(FILE *,guchar *,int,int,int,int,int,int,int);
|
||||
extern gint32 ToL (guchar *);
|
||||
extern void FromL (gint32,
|
||||
guchar *);
|
||||
extern gint16 ToS (guchar *);
|
||||
extern void FromS (gint16,
|
||||
guchar *);
|
||||
extern gint32 ReadBMP (gchar *);
|
||||
extern GStatusType WriteBMP (gchar *,
|
||||
gint32,
|
||||
gint32);
|
||||
extern gint ReadColorMap (FILE *,
|
||||
guchar[256][3],
|
||||
gint,
|
||||
gint,
|
||||
gint *);
|
||||
extern Image ReadImage (FILE *,
|
||||
gint,
|
||||
gint,
|
||||
guchar[256][3],
|
||||
gint,
|
||||
gint,
|
||||
gint,
|
||||
gint,
|
||||
gint);
|
||||
extern void WriteColorMap (FILE *,
|
||||
gint *,
|
||||
gint *,
|
||||
gint *,
|
||||
gint);
|
||||
extern void WriteImage (FILE *,
|
||||
guchar *,
|
||||
gint,
|
||||
gint,
|
||||
gint,
|
||||
gint,
|
||||
gint,
|
||||
gint,
|
||||
gint);
|
||||
|
||||
extern int interactive_bmp;
|
||||
extern char *prog_name;
|
||||
extern char *filename;
|
||||
extern FILE *errorfile;
|
||||
extern gint interactive_bmp;
|
||||
extern gchar *prog_name;
|
||||
extern gchar *filename;
|
||||
extern FILE *errorfile;
|
||||
|
||||
extern struct Bitmap_File_Head_Struct
|
||||
{
|
||||
unsigned long bfSize; /* 02 */
|
||||
unsigned long reserverd; /* 06 */
|
||||
unsigned long bfOffs; /* 0A */
|
||||
unsigned long biSize; /* 0E */
|
||||
}Bitmap_File_Head;
|
||||
{
|
||||
gulong bfSize; /* 02 */
|
||||
gulong reserverd; /* 06 */
|
||||
gulong bfOffs; /* 0A */
|
||||
gulong biSize; /* 0E */
|
||||
} Bitmap_File_Head;
|
||||
|
||||
extern struct Bitmap_Head_Struct
|
||||
{
|
||||
unsigned long biWidth; /* 12 */
|
||||
unsigned long biHeight; /* 16 */
|
||||
unsigned short biPlanes; /* 1A */
|
||||
unsigned short biBitCnt; /* 1C */
|
||||
unsigned long biCompr; /* 1E */
|
||||
unsigned long biSizeIm; /* 22 */
|
||||
unsigned long biXPels; /* 26 */
|
||||
unsigned long biYPels; /* 2A */
|
||||
unsigned long biClrUsed; /* 2E */
|
||||
unsigned long biClrImp; /* 32 */
|
||||
/* 36 */
|
||||
}Bitmap_Head;
|
||||
{
|
||||
gulong biWidth; /* 12 */
|
||||
gulong biHeight; /* 16 */
|
||||
gushort biPlanes; /* 1A */
|
||||
gushort biBitCnt; /* 1C */
|
||||
gulong biCompr; /* 1E */
|
||||
gulong biSizeIm; /* 22 */
|
||||
gulong biXPels; /* 26 */
|
||||
gulong biYPels; /* 2A */
|
||||
gulong biClrUsed; /* 2E */
|
||||
gulong biClrImp; /* 32 */
|
||||
/* 36 */
|
||||
} Bitmap_Head;
|
||||
|
||||
extern struct Bitmap_OS2_Head_Struct
|
||||
{
|
||||
unsigned short bcWidth; /* 12 */
|
||||
unsigned short bcHeight; /* 14 */
|
||||
unsigned short bcPlanes; /* 16 */
|
||||
unsigned short bcBitCnt; /* 18 */
|
||||
}Bitmap_OS2_Head;
|
||||
{
|
||||
gushort bcWidth; /* 12 */
|
||||
gushort bcHeight; /* 14 */
|
||||
gushort bcPlanes; /* 16 */
|
||||
gushort bcBitCnt; /* 18 */
|
||||
} Bitmap_OS2_Head;
|
||||
|
||||
|
@ -23,23 +23,28 @@
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include "bmp.h"
|
||||
|
||||
#include <libgimp/gimp.h>
|
||||
|
||||
#include "bmp.h"
|
||||
|
||||
#include "libgimp/stdplugins-intl.h"
|
||||
|
||||
|
||||
gint32
|
||||
ReadBMP (char *name)
|
||||
ReadBMP (gchar *name)
|
||||
{
|
||||
FILE *fd;
|
||||
char *temp_buf;
|
||||
char buf[5];
|
||||
int ColormapSize, SpeicherZeile, Maps, Grey;
|
||||
unsigned char ColorMap[256][3];
|
||||
gchar *temp_buf;
|
||||
gchar buf[5];
|
||||
gint ColormapSize, SpeicherZeile, Maps, Grey;
|
||||
guchar ColorMap[256][3];
|
||||
guchar puffer[50];
|
||||
gint32 image_ID;
|
||||
|
||||
@ -79,35 +84,36 @@ ReadBMP (char *name)
|
||||
|
||||
/* bring them to the right byteorder. Not too nice, but it should work */
|
||||
|
||||
Bitmap_File_Head.bfSize=ToL(&puffer[0]);
|
||||
Bitmap_File_Head.reserverd=ToL(&puffer[4]);
|
||||
Bitmap_File_Head.bfOffs=ToL(&puffer[8]);
|
||||
Bitmap_File_Head.biSize=ToL(&puffer[12]);
|
||||
Bitmap_File_Head.bfSize = ToL (&puffer[0]);
|
||||
Bitmap_File_Head.reserverd = ToL (&puffer[4]);
|
||||
Bitmap_File_Head.bfOffs = ToL (&puffer[8]);
|
||||
Bitmap_File_Head.biSize = ToL (&puffer[12]);
|
||||
|
||||
/* Is it a Windows (R) Bitmap or not */
|
||||
|
||||
if (Bitmap_File_Head.biSize!=40)
|
||||
if (Bitmap_File_Head.biSize != 40)
|
||||
{
|
||||
g_warning("OS/2 unsupported!\n");
|
||||
g_warning ("OS/2 unsupported!\n");
|
||||
if (!ReadOK (fd, puffer, Bitmap_File_Head.biSize))
|
||||
{
|
||||
g_message (_("%s: error reading BMP file header\n"), prog_name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
Bitmap_OS2_Head.bcWidth=ToS(&puffer[0]);
|
||||
Bitmap_OS2_Head.bcHeight=ToS(&puffer[2]);
|
||||
Bitmap_OS2_Head.bcPlanes=ToS(&puffer[4]);
|
||||
Bitmap_OS2_Head.bcBitCnt=ToS(&puffer[6]);
|
||||
Bitmap_OS2_Head.bcWidth = ToS (&puffer[0]);
|
||||
Bitmap_OS2_Head.bcHeight = ToS (&puffer[2]);
|
||||
Bitmap_OS2_Head.bcPlanes = ToS (&puffer[4]);
|
||||
Bitmap_OS2_Head.bcBitCnt = ToS (&puffer[6]);
|
||||
|
||||
Bitmap_Head.biPlanes=Bitmap_OS2_Head.bcPlanes;
|
||||
Bitmap_Head.biBitCnt=Bitmap_OS2_Head.bcBitCnt;
|
||||
Bitmap_File_Head.bfSize=(Bitmap_File_Head.bfSize*4)-(Bitmap_File_Head.bfOffs*3);
|
||||
Bitmap_Head.biHeight=Bitmap_OS2_Head.bcHeight;
|
||||
Bitmap_Head.biWidth=Bitmap_OS2_Head.bcWidth;
|
||||
Bitmap_Head.biClrUsed=0;
|
||||
Bitmap_Head.biCompr=0;
|
||||
Maps=3;
|
||||
Bitmap_Head.biPlanes = Bitmap_OS2_Head.bcPlanes;
|
||||
Bitmap_Head.biBitCnt = Bitmap_OS2_Head.bcBitCnt;
|
||||
Bitmap_File_Head.bfSize = ((Bitmap_File_Head.bfSize * 4) -
|
||||
(Bitmap_File_Head.bfOffs * 3));
|
||||
Bitmap_Head.biHeight = Bitmap_OS2_Head.bcHeight;
|
||||
Bitmap_Head.biWidth = Bitmap_OS2_Head.bcWidth;
|
||||
Bitmap_Head.biClrUsed = 0;
|
||||
Bitmap_Head.biCompr = 0;
|
||||
Maps = 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -116,36 +122,45 @@ ReadBMP (char *name)
|
||||
g_message (_("%s: error reading BMP file header\n"), prog_name);
|
||||
return -1;
|
||||
}
|
||||
Bitmap_Head.biWidth=ToL(&puffer[0x00]); /* 12 */
|
||||
Bitmap_Head.biHeight=ToL(&puffer[0x04]); /* 16 */
|
||||
Bitmap_Head.biPlanes=ToS(&puffer[0x08]); /* 1A */
|
||||
Bitmap_Head.biBitCnt=ToS(&puffer[0x0A]); /* 1C */
|
||||
Bitmap_Head.biCompr=ToL(&puffer[0x0C]); /* 1E */
|
||||
Bitmap_Head.biSizeIm=ToL(&puffer[0x10]); /* 22 */
|
||||
Bitmap_Head.biXPels=ToL(&puffer[0x14]); /* 26 */
|
||||
Bitmap_Head.biYPels=ToL(&puffer[0x18]); /* 2A */
|
||||
Bitmap_Head.biClrUsed=ToL(&puffer[0x1C]); /* 2E */
|
||||
Bitmap_Head.biClrImp=ToL(&puffer[0x20]); /* 32 */
|
||||
Bitmap_Head.biWidth =ToL (&puffer[0x00]); /* 12 */
|
||||
Bitmap_Head.biHeight =ToL (&puffer[0x04]); /* 16 */
|
||||
Bitmap_Head.biPlanes =ToS (&puffer[0x08]); /* 1A */
|
||||
Bitmap_Head.biBitCnt =ToS (&puffer[0x0A]); /* 1C */
|
||||
Bitmap_Head.biCompr =ToL (&puffer[0x0C]); /* 1E */
|
||||
Bitmap_Head.biSizeIm =ToL (&puffer[0x10]); /* 22 */
|
||||
Bitmap_Head.biXPels =ToL (&puffer[0x14]); /* 26 */
|
||||
Bitmap_Head.biYPels =ToL (&puffer[0x18]); /* 2A */
|
||||
Bitmap_Head.biClrUsed =ToL (&puffer[0x1C]); /* 2E */
|
||||
Bitmap_Head.biClrImp =ToL (&puffer[0x20]); /* 32 */
|
||||
/* 36 */
|
||||
Maps=4;
|
||||
Maps = 4;
|
||||
}
|
||||
|
||||
/* This means wrong file Format. I test this because it could crash the */
|
||||
/* entire gimp. */
|
||||
/* This means wrong file Format. I test this because it could crash the
|
||||
* entire gimp.
|
||||
*/
|
||||
|
||||
if (Bitmap_Head.biBitCnt>24)
|
||||
{
|
||||
g_message(_("%s: too many colors: %u\n"),prog_name,
|
||||
(unsigned int) Bitmap_Head.biBitCnt);
|
||||
return -1;
|
||||
}
|
||||
if (Bitmap_Head.biBitCnt > 24)
|
||||
{
|
||||
g_message (_("%s: too many colors: %u\n"), prog_name,
|
||||
(guint) Bitmap_Head.biBitCnt);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* There should be some colors used! */
|
||||
|
||||
ColormapSize = (Bitmap_File_Head.bfOffs-Bitmap_File_Head.biSize-14) / Maps;
|
||||
if ((Bitmap_Head.biClrUsed==0) && (Bitmap_Head.biBitCnt<24)) Bitmap_Head.biClrUsed=ColormapSize;
|
||||
if (Bitmap_Head.biBitCnt==24) SpeicherZeile=((Bitmap_File_Head.bfSize-Bitmap_File_Head.bfOffs)/Bitmap_Head.biHeight);
|
||||
else SpeicherZeile=((Bitmap_File_Head.bfSize-Bitmap_File_Head.bfOffs)/Bitmap_Head.biHeight)*(8/Bitmap_Head.biBitCnt);
|
||||
ColormapSize = (Bitmap_File_Head.bfOffs - Bitmap_File_Head.biSize - 14) / Maps;
|
||||
|
||||
if ((Bitmap_Head.biClrUsed == 0) &&
|
||||
(Bitmap_Head.biBitCnt < 24))
|
||||
Bitmap_Head.biClrUsed = ColormapSize;
|
||||
|
||||
if (Bitmap_Head.biBitCnt == 24)
|
||||
SpeicherZeile = ((Bitmap_File_Head.bfSize - Bitmap_File_Head.bfOffs) /
|
||||
Bitmap_Head.biHeight);
|
||||
else
|
||||
SpeicherZeile = ((Bitmap_File_Head.bfSize - Bitmap_File_Head.bfOffs) /
|
||||
Bitmap_Head.biHeight) * (8 / Bitmap_Head.biBitCnt);
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("\nSize: %u, Colors: %u, Bits: %u, Width: %u, Height: %u, Comp: %u, Zeile: %u\n",
|
||||
@ -155,7 +170,8 @@ ReadBMP (char *name)
|
||||
|
||||
/* Get the Colormap */
|
||||
|
||||
if (ReadColorMap(fd, ColorMap, ColormapSize, Maps, &Grey) == -1) return -1;
|
||||
if (ReadColorMap (fd, ColorMap, ColormapSize, Maps, &Grey) == -1)
|
||||
return -1;
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("Colormap read\n");
|
||||
@ -175,8 +191,8 @@ ReadBMP (char *name)
|
||||
#ifdef GIMP_HAVE_RESOLUTION_INFO
|
||||
{
|
||||
/* quick hack by the muppet, scott@asofyet.org, 19 dec 1999 */
|
||||
double xresolution;
|
||||
double yresolution;
|
||||
gdouble xresolution;
|
||||
gdouble yresolution;
|
||||
|
||||
/*
|
||||
* xresolution and yresolution are in dots per inch.
|
||||
@ -202,14 +218,14 @@ ReadBMP (char *name)
|
||||
}
|
||||
|
||||
gint
|
||||
ReadColorMap (FILE *fd,
|
||||
unsigned char buffer[256][3],
|
||||
int number,
|
||||
int size,
|
||||
int *grey)
|
||||
ReadColorMap (FILE *fd,
|
||||
guchar buffer[256][3],
|
||||
gint number,
|
||||
gint size,
|
||||
gint *grey)
|
||||
{
|
||||
int i;
|
||||
unsigned char rgb[4];
|
||||
gint i;
|
||||
guchar rgb[4];
|
||||
|
||||
*grey=(number>2);
|
||||
for (i = 0; i < number ; i++)
|
||||
@ -222,51 +238,55 @@ ReadColorMap (FILE *fd,
|
||||
|
||||
/* Bitmap save the colors in another order! But change only once! */
|
||||
|
||||
if (size==4) {
|
||||
buffer[i][0] = rgb[2];
|
||||
buffer[i][1] = rgb[1];
|
||||
buffer[i][2] = rgb[0];
|
||||
} else {
|
||||
/* this one is for old os2 Bitmaps, but it dosn't work well */
|
||||
buffer[i][0] = rgb[1];
|
||||
buffer[i][1] = rgb[0];
|
||||
buffer[i][2] = rgb[2];
|
||||
}
|
||||
*grey=((*grey) && (rgb[0]==rgb[1]) && (rgb[1]==rgb[2]));
|
||||
if (size == 4)
|
||||
{
|
||||
buffer[i][0] = rgb[2];
|
||||
buffer[i][1] = rgb[1];
|
||||
buffer[i][2] = rgb[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
/* this one is for old os2 Bitmaps, but it dosn't work well */
|
||||
buffer[i][0] = rgb[1];
|
||||
buffer[i][1] = rgb[0];
|
||||
buffer[i][2] = rgb[2];
|
||||
}
|
||||
*grey = ((*grey) && (rgb[0]==rgb[1]) && (rgb[1]==rgb[2]));
|
||||
}
|
||||
return(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Image
|
||||
ReadImage (FILE *fd,
|
||||
int len,
|
||||
int height,
|
||||
unsigned char cmap[256][3],
|
||||
int ncols,
|
||||
int bpp,
|
||||
int compression,
|
||||
int spzeile,
|
||||
int grey)
|
||||
ReadImage (FILE *fd,
|
||||
gint len,
|
||||
gint height,
|
||||
guchar cmap[256][3],
|
||||
gint ncols,
|
||||
gint bpp,
|
||||
gint compression,
|
||||
gint spzeile,
|
||||
gint grey)
|
||||
{
|
||||
char *name_buf;
|
||||
unsigned char v,wieviel;
|
||||
gchar *name_buf;
|
||||
guchar v,wieviel;
|
||||
GPixelRgn pixel_rgn;
|
||||
char buf[16];
|
||||
int xpos = 0, ypos = 0;
|
||||
gchar buf[16];
|
||||
gint xpos = 0, ypos = 0;
|
||||
Image image;
|
||||
gint32 layer;
|
||||
GDrawable *drawable;
|
||||
guchar *dest, *temp;
|
||||
guchar gimp_cmap[768];
|
||||
long rowstride, channels;
|
||||
int i, j, cur_progress, max_progress, egal;
|
||||
gint i, j, cur_progress, max_progress, egal;
|
||||
|
||||
/* Make a new image in the gimp */
|
||||
|
||||
if (grey)
|
||||
{
|
||||
image = gimp_image_new (len, height, GRAY);
|
||||
layer = gimp_layer_new (image, _("Background"), len, height, GRAY_IMAGE, 100, NORMAL_MODE);
|
||||
layer = gimp_layer_new (image, _("Background"),
|
||||
len, height, GRAY_IMAGE, 100, NORMAL_MODE);
|
||||
channels = 1;
|
||||
}
|
||||
else
|
||||
@ -274,13 +294,15 @@ ReadImage (FILE *fd,
|
||||
if (bpp<24)
|
||||
{
|
||||
image = gimp_image_new (len, height, INDEXED);
|
||||
layer = gimp_layer_new (image, _("Background"), len, height, INDEXED_IMAGE, 100, NORMAL_MODE);
|
||||
layer = gimp_layer_new (image, _("Background"),
|
||||
len, height, INDEXED_IMAGE, 100, NORMAL_MODE);
|
||||
channels = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
image = gimp_image_new (len, height, RGB);
|
||||
layer = gimp_layer_new (image, _("Background"), len, height, RGB_IMAGE, 100, NORMAL_MODE);
|
||||
layer = gimp_layer_new (image, _("Background"),
|
||||
len, height, RGB_IMAGE, 100, NORMAL_MODE);
|
||||
channels = 3;
|
||||
}
|
||||
}
|
||||
@ -296,13 +318,13 @@ ReadImage (FILE *fd,
|
||||
dest = g_malloc(drawable->width*drawable->height*channels);
|
||||
rowstride = drawable->width * channels;
|
||||
|
||||
ypos=height-1; /* Bitmaps begin in the lower left corner */
|
||||
ypos = height - 1; /* Bitmaps begin in the lower left corner */
|
||||
cur_progress = 0;
|
||||
max_progress = height;
|
||||
|
||||
if (bpp==24)
|
||||
if (bpp == 24)
|
||||
{
|
||||
while (ReadOK(fd,buf,3))
|
||||
while (ReadOK (fd, buf, 3))
|
||||
{
|
||||
temp = dest + (ypos * rowstride) + (xpos * channels);
|
||||
*temp=buf[2];
|
||||
@ -313,124 +335,156 @@ ReadImage (FILE *fd,
|
||||
xpos++;
|
||||
if (xpos == len)
|
||||
{
|
||||
egal=ReadOK(fd,buf,spzeile-(len*3));
|
||||
egal=ReadOK (fd, buf, spzeile - (len * 3));
|
||||
ypos--;
|
||||
xpos=0;
|
||||
xpos = 0;
|
||||
|
||||
cur_progress++;
|
||||
if ((interactive_bmp) &&((cur_progress % 5) == 0))
|
||||
gimp_progress_update ((double) cur_progress / (double) max_progress);
|
||||
if ((interactive_bmp) &&
|
||||
((cur_progress % 5) == 0))
|
||||
gimp_progress_update ((gdouble) cur_progress /
|
||||
(gdouble) max_progress);
|
||||
}
|
||||
if (ypos < 0) break;
|
||||
if (ypos < 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
else { switch(compression)
|
||||
else
|
||||
{
|
||||
case 0: /* uncompressed */
|
||||
{
|
||||
while (ReadOK(fd,&v,1))
|
||||
switch(compression)
|
||||
{
|
||||
case 0: /* uncompressed */
|
||||
{
|
||||
for (i=1;(i<=(8/bpp)) && (xpos<len);i++,xpos++)
|
||||
{
|
||||
temp = dest + (ypos * rowstride) + (xpos * channels);
|
||||
*temp=( v & ( ((1<<bpp)-1) << (8-(i*bpp)) ) ) >> (8-(i*bpp));
|
||||
if (grey) *temp=cmap[*temp][0];
|
||||
}
|
||||
if (xpos == len)
|
||||
{
|
||||
egal=ReadOK(fd,buf,(spzeile-len)/(8/bpp));
|
||||
ypos--;
|
||||
xpos=0;
|
||||
cur_progress++;
|
||||
if ((interactive_bmp) && ((cur_progress % 5) == 0))
|
||||
gimp_progress_update ((double) cur_progress / (double) max_progress);
|
||||
}
|
||||
if (ypos < 0) break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: /* Compressed images */
|
||||
{
|
||||
while (TRUE)
|
||||
{
|
||||
egal=ReadOK(fd,buf,2);
|
||||
if ((unsigned char) buf[0]!=0)
|
||||
/* Count + Color - record */
|
||||
while (ReadOK (fd, &v, 1))
|
||||
{
|
||||
for (j=0;((unsigned char) j < (unsigned char) buf[0]) && (xpos<len);)
|
||||
for (i = 1; (i <= (8 / bpp)) && (xpos < len); i++, xpos++)
|
||||
{
|
||||
temp = dest + (ypos * rowstride) + (xpos * channels);
|
||||
*temp=( v & ( ((1<<bpp)-1) << (8-(i*bpp)) ) ) >> (8-(i*bpp));
|
||||
if (grey)
|
||||
*temp = cmap[*temp][0];
|
||||
}
|
||||
if (xpos == len)
|
||||
{
|
||||
egal = ReadOK (fd, buf, (spzeile - len) / (8 / bpp));
|
||||
ypos--;
|
||||
xpos = 0;
|
||||
|
||||
cur_progress++;
|
||||
if ((interactive_bmp) &&
|
||||
((cur_progress % 5) == 0))
|
||||
gimp_progress_update ((gdouble) cur_progress /
|
||||
(gdouble) max_progress);
|
||||
}
|
||||
if (ypos < 0)
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: /* Compressed images */
|
||||
{
|
||||
while (TRUE)
|
||||
{
|
||||
egal = ReadOK (fd, buf, 2);
|
||||
if ((guchar) buf[0] != 0)
|
||||
/* Count + Color - record */
|
||||
{
|
||||
for (j = 0; ((guchar) j < (guchar) buf[0]) && (xpos < len);)
|
||||
{
|
||||
#ifdef DEBUG2
|
||||
printf("%u %u | ",xpos,len);
|
||||
printf("%u %u | ",xpos,len);
|
||||
#endif
|
||||
for (i=1;((i<=(8/bpp)) && (xpos<len) && ((unsigned char) j < (unsigned char) buf[0]));i++,xpos++,j++)
|
||||
{
|
||||
temp = dest + (ypos * rowstride) + (xpos * channels);
|
||||
*temp=( buf[1] & ( ((1<<bpp)-1) << (8-(i*bpp)) ) ) >> (8-(i*bpp));
|
||||
if (grey) *temp=cmap[*temp][0];
|
||||
for (i = 1;
|
||||
((i <= (8 / bpp)) &&
|
||||
(xpos < len) &&
|
||||
((guchar) j < (unsigned char) buf[0]));
|
||||
i++, xpos++, j++)
|
||||
{
|
||||
temp = dest + (ypos * rowstride) + (xpos * channels);
|
||||
*temp = (buf[1] & (((1<<bpp)-1) << (8 - (i * bpp)))) >> (8 - (i * bpp));
|
||||
if (grey)
|
||||
*temp = cmap[*temp][0];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (((unsigned char) buf[0]==0) && ((unsigned char) buf[1]>2))
|
||||
/* uncompressed record */
|
||||
{
|
||||
wieviel=buf[1];
|
||||
for (j=0;j<wieviel;j+=(8/bpp))
|
||||
if (((guchar) buf[0] == 0) && ((guchar) buf[1] > 2))
|
||||
/* uncompressed record */
|
||||
{
|
||||
egal=ReadOK(fd,&v,1);
|
||||
i=1;
|
||||
while ((i<=(8/bpp)) && (xpos<len))
|
||||
wieviel = buf[1];
|
||||
for (j = 0; j < wieviel; j += (8 / bpp))
|
||||
{
|
||||
temp = dest + (ypos * rowstride) + (xpos * channels);
|
||||
*temp=(v & ( ((1<<bpp)-1) << (8-(i*bpp)) ) ) >> (8-(i*bpp));
|
||||
if (grey) *temp=cmap[*temp][0];
|
||||
i++;
|
||||
xpos++;
|
||||
egal = ReadOK (fd, &v, 1);
|
||||
i = 1;
|
||||
while ((i <= (8 / bpp)) && (xpos < len))
|
||||
{
|
||||
temp = dest + (ypos * rowstride) + (xpos * channels);
|
||||
*temp = (v & (((1<<bpp)-1) << (8-(i*bpp)))) >> (8-(i*bpp));
|
||||
if (grey)
|
||||
*temp = cmap[*temp][0];
|
||||
i++;
|
||||
xpos++;
|
||||
}
|
||||
}
|
||||
|
||||
if ((wieviel % 2) && (bpp==4))
|
||||
wieviel++;
|
||||
|
||||
if ((wieviel / (8 / bpp)) % 2)
|
||||
egal = ReadOK (fd, &v, 1);
|
||||
/*if odd(x div (8 div bpp )) then blockread(f,z^,1);*/
|
||||
}
|
||||
if (((guchar) buf[0] == 0) && ((guchar) buf[1]==0))
|
||||
/* Zeilenende */
|
||||
{
|
||||
ypos--;
|
||||
xpos = 0;
|
||||
|
||||
cur_progress++;
|
||||
if ((interactive_bmp) &&
|
||||
((cur_progress % 5) == 0))
|
||||
gimp_progress_update ((gdouble) cur_progress /
|
||||
(gdouble) max_progress);
|
||||
}
|
||||
if (((guchar) buf[0]==0) && ((guchar) buf[1]==1))
|
||||
/* Bitmapende */
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (((guchar) buf[0]==0) && ((guchar) buf[1]==2))
|
||||
/* Deltarecord */
|
||||
{
|
||||
xpos += (guchar) buf[2];
|
||||
ypos += (guchar) buf[3];
|
||||
}
|
||||
if ((wieviel % 2) && (bpp==4)) wieviel++;
|
||||
if ( (wieviel / (8/bpp)) % 2) egal=ReadOK(fd,&v,1);
|
||||
/*if odd(x div (8 div bpp )) then blockread(f,z^,1);*/
|
||||
}
|
||||
if (((unsigned char) buf[0]==0) && ((unsigned char) buf[1]==0))
|
||||
/* Zeilenende */
|
||||
{
|
||||
ypos--;
|
||||
xpos=0;
|
||||
cur_progress++;
|
||||
if ((interactive_bmp) && ((cur_progress % 5) == 0))
|
||||
gimp_progress_update ((double) cur_progress / (double) max_progress);
|
||||
}
|
||||
if (((unsigned char) buf[0]==0) && ((unsigned char) buf[1]==1))
|
||||
/* Bitmapende */
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (((unsigned char) buf[0]==0) && ((unsigned char) buf[1]==2))
|
||||
/* Deltarecord */
|
||||
{
|
||||
xpos+=(unsigned char) buf[2];
|
||||
ypos+=(unsigned char) buf[3];
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
fclose (fd);
|
||||
if (bpp < 24)
|
||||
for (i = 0, j = 0; i < ncols; i++)
|
||||
{
|
||||
gimp_cmap[j++] = cmap[i][0];
|
||||
gimp_cmap[j++] = cmap[i][1];
|
||||
gimp_cmap[j++] = cmap[i][2];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fclose(fd);
|
||||
if (bpp<24) for (i = 0, j = 0; i < ncols; i++)
|
||||
{
|
||||
gimp_cmap[j++] = cmap[i][0];
|
||||
gimp_cmap[j++] = cmap[i][1];
|
||||
gimp_cmap[j++] = cmap[i][2];
|
||||
}
|
||||
if (interactive_bmp)
|
||||
gimp_progress_update (1);
|
||||
|
||||
if (interactive_bmp) gimp_progress_update (1);
|
||||
gimp_pixel_rgn_init(&pixel_rgn, drawable, 0, 0, drawable->width, drawable->height, TRUE, FALSE);
|
||||
gimp_pixel_rgn_set_rect(&pixel_rgn, dest, 0, 0, drawable->width, drawable->height);
|
||||
if ((!grey) && (bpp<24)) gimp_image_set_cmap(image, gimp_cmap, ncols);
|
||||
gimp_drawable_flush(drawable);
|
||||
gimp_drawable_detach(drawable);
|
||||
g_free(dest);
|
||||
gimp_pixel_rgn_init (&pixel_rgn, drawable,
|
||||
0, 0, drawable->width, drawable->height, TRUE, FALSE);
|
||||
gimp_pixel_rgn_set_rect (&pixel_rgn, dest,
|
||||
0, 0, drawable->width, drawable->height);
|
||||
|
||||
return (image);
|
||||
if ((!grey) && (bpp<24))
|
||||
gimp_image_set_cmap (image, gimp_cmap, ncols);
|
||||
|
||||
gimp_drawable_flush (drawable);
|
||||
gimp_drawable_detach (drawable);
|
||||
g_free (dest);
|
||||
|
||||
return image;
|
||||
}
|
||||
|
@ -37,14 +37,18 @@
|
||||
#endif
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include <libgimp/gimp.h>
|
||||
#include <libgimp/gimpui.h>
|
||||
|
||||
#include "bmp.h"
|
||||
|
||||
#include "libgimp/stdplugins-intl.h"
|
||||
|
||||
guchar *pixels;
|
||||
int cur_progress;
|
||||
gint cur_progress;
|
||||
|
||||
int max_progress;
|
||||
gint max_progress;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
@ -56,40 +60,40 @@ static BMPSaveInterface gsint =
|
||||
FALSE /* run */
|
||||
};
|
||||
|
||||
int encoded = 0;
|
||||
gint encoded = 0;
|
||||
|
||||
|
||||
static gint save_dialog (void);
|
||||
static void save_close_callback (GtkWidget *widget, gpointer data);
|
||||
static void save_ok_callback (GtkWidget *widget, gpointer data);
|
||||
static void save_toggle_update (GtkWidget *widget, gpointer data);
|
||||
static gint save_dialog (void);
|
||||
static void save_ok_callback (GtkWidget *widget,
|
||||
gpointer data);
|
||||
|
||||
gint
|
||||
WriteBMP (char *filename,
|
||||
GStatusType
|
||||
WriteBMP (gchar *filename,
|
||||
gint32 image,
|
||||
gint32 drawable_ID)
|
||||
{
|
||||
FILE *outfile;
|
||||
int Red[MAXCOLORS];
|
||||
int Green[MAXCOLORS];
|
||||
int Blue[MAXCOLORS];
|
||||
unsigned char *cmap;
|
||||
int rows, cols, Spcols, channels, MapSize, SpZeile;
|
||||
long BitsPerPixel;
|
||||
int colors;
|
||||
char *temp_buf;
|
||||
gint Red[MAXCOLORS];
|
||||
gint Green[MAXCOLORS];
|
||||
gint Blue[MAXCOLORS];
|
||||
guchar *cmap;
|
||||
gint rows, cols, Spcols, channels, MapSize, SpZeile;
|
||||
glong BitsPerPixel;
|
||||
gint colors;
|
||||
gchar *temp_buf;
|
||||
guchar *pixels;
|
||||
GPixelRgn pixel_rgn;
|
||||
GDrawable *drawable;
|
||||
GDrawableType drawable_type;
|
||||
guchar puffer[50];
|
||||
int i;
|
||||
gint i;
|
||||
|
||||
/* first: can we save this image? */
|
||||
|
||||
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);
|
||||
gimp_pixel_rgn_init (&pixel_rgn, drawable,
|
||||
0, 0, drawable->width, drawable->height, FALSE, FALSE);
|
||||
switch (drawable_type)
|
||||
{
|
||||
case RGB_IMAGE:
|
||||
@ -98,7 +102,7 @@ WriteBMP (char *filename,
|
||||
break;
|
||||
default:
|
||||
g_message(_("bmp: cannot operate on unknown image types or alpha images"));
|
||||
gimp_quit ();
|
||||
return STATUS_EXECUTION_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -107,65 +111,69 @@ WriteBMP (char *filename,
|
||||
switch (drawable_type)
|
||||
{
|
||||
case RGB_IMAGE:
|
||||
colors = 0;
|
||||
colors = 0;
|
||||
BitsPerPixel = 24;
|
||||
MapSize = 0;
|
||||
channels = 3;
|
||||
MapSize = 0;
|
||||
channels = 3;
|
||||
break;
|
||||
case GRAY_IMAGE:
|
||||
colors = 256;
|
||||
BitsPerPixel=8;
|
||||
MapSize=1024;
|
||||
channels = 1;
|
||||
colors = 256;
|
||||
BitsPerPixel = 8;
|
||||
MapSize = 1024;
|
||||
channels = 1;
|
||||
for (i = 0; i < colors; i++)
|
||||
{
|
||||
Red[i] = i;
|
||||
Red[i] = i;
|
||||
Green[i] = i;
|
||||
Blue[i] = i;
|
||||
Blue[i] = i;
|
||||
}
|
||||
break;
|
||||
case INDEXED_IMAGE:
|
||||
cmap = gimp_image_get_cmap (image, &colors);
|
||||
MapSize = 4*colors;
|
||||
cmap = gimp_image_get_cmap (image, &colors);
|
||||
MapSize = 4 * colors;
|
||||
channels = 1;
|
||||
if (colors>16) BitsPerPixel=8; else if (colors>2) BitsPerPixel=4;
|
||||
else BitsPerPixel=1;
|
||||
|
||||
if (colors > 16)
|
||||
BitsPerPixel = 8;
|
||||
else if (colors > 2)
|
||||
BitsPerPixel = 4;
|
||||
else
|
||||
BitsPerPixel = 1;
|
||||
|
||||
for (i = 0; i < colors; i++)
|
||||
{
|
||||
Red[i] = *cmap++;
|
||||
Red[i] = *cmap++;
|
||||
Green[i] = *cmap++;
|
||||
Blue[i] = *cmap++;
|
||||
Blue[i] = *cmap++;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
fprintf (stderr, "%s: This should not happen\n", prog_name);
|
||||
return FALSE;
|
||||
return STATUS_EXECUTION_ERROR;
|
||||
}
|
||||
|
||||
/* Perhaps someone wants RLE encoded Bitmaps */
|
||||
encoded = 0;
|
||||
if ((BitsPerPixel == 8 || BitsPerPixel == 4) && interactive_bmp)
|
||||
{
|
||||
if (! save_dialog ())
|
||||
return -1;
|
||||
}
|
||||
|
||||
encoded = 0;
|
||||
if ((BitsPerPixel == 8 || BitsPerPixel == 4) && interactive_bmp)
|
||||
{
|
||||
if (! save_dialog ())
|
||||
return STATUS_CANCEL;
|
||||
}
|
||||
|
||||
/* Let's take some file */
|
||||
outfile = fopen (filename, "wb");
|
||||
if (!outfile)
|
||||
{
|
||||
g_message (_("can't open %s\n"), filename);
|
||||
return -1;
|
||||
return STATUS_EXECUTION_ERROR;
|
||||
}
|
||||
|
||||
|
||||
/* fetch the image */
|
||||
|
||||
pixels = (guchar *) g_malloc(drawable->width*drawable->height*channels);
|
||||
gimp_pixel_rgn_get_rect(&pixel_rgn, pixels, 0, 0, drawable->width, drawable->height);
|
||||
|
||||
pixels = g_new (guchar, drawable->width * drawable->height * channels);
|
||||
gimp_pixel_rgn_get_rect (&pixel_rgn, pixels,
|
||||
0, 0, drawable->width, drawable->height);
|
||||
|
||||
/* And let's begin the progress */
|
||||
|
||||
if (interactive_bmp)
|
||||
{
|
||||
temp_buf = g_strdup_printf (_("Saving %s:"), filename);
|
||||
@ -174,37 +182,53 @@ WriteBMP (char *filename,
|
||||
}
|
||||
cur_progress = 0;
|
||||
max_progress = drawable->height;
|
||||
|
||||
|
||||
/* Now, we need some further information ... */
|
||||
|
||||
cols = drawable->width;
|
||||
rows = drawable->height;
|
||||
|
||||
|
||||
/* ... that we write to our headers. */
|
||||
|
||||
if ((BitsPerPixel != 24) && (cols % (8/BitsPerPixel))) Spcols=(((cols / (8/BitsPerPixel))+1)*(8/BitsPerPixel)); else Spcols=cols;
|
||||
if ((((Spcols*BitsPerPixel)/8) % 4) == 0) SpZeile=((Spcols*BitsPerPixel)/8);
|
||||
else SpZeile=((int)(((Spcols*BitsPerPixel)/8)/4)+1)*4;
|
||||
Bitmap_File_Head.bfSize=0x36+MapSize+(rows*SpZeile);
|
||||
Bitmap_File_Head.reserverd=0;
|
||||
Bitmap_File_Head.bfOffs=0x36+MapSize;
|
||||
Bitmap_File_Head.biSize=40;
|
||||
Bitmap_Head.biWidth=cols;
|
||||
Bitmap_Head.biHeight=rows;
|
||||
Bitmap_Head.biPlanes=1;
|
||||
Bitmap_Head.biBitCnt=BitsPerPixel;
|
||||
if (encoded==0) Bitmap_Head.biCompr=0;
|
||||
else if (BitsPerPixel==8) Bitmap_Head.biCompr=1;
|
||||
else if (BitsPerPixel==4) Bitmap_Head.biCompr=2;
|
||||
else Bitmap_Head.biCompr=0;
|
||||
Bitmap_Head.biSizeIm=SpZeile*rows;
|
||||
if ((BitsPerPixel != 24) &&
|
||||
(cols % (8/BitsPerPixel)))
|
||||
Spcols = (((cols / (8 / BitsPerPixel)) + 1) * (8 / BitsPerPixel));
|
||||
else
|
||||
Spcols = cols;
|
||||
|
||||
if ((((Spcols * BitsPerPixel) / 8) % 4) == 0)
|
||||
SpZeile = ((Spcols * BitsPerPixel) / 8);
|
||||
else
|
||||
SpZeile = ((gint) (((Spcols * BitsPerPixel) / 8) / 4) + 1) * 4;
|
||||
|
||||
Bitmap_File_Head.bfSize = 0x36 + MapSize + (rows * SpZeile);
|
||||
Bitmap_File_Head.reserverd = 0;
|
||||
Bitmap_File_Head.bfOffs = 0x36 + MapSize;
|
||||
Bitmap_File_Head.biSize = 40;
|
||||
|
||||
Bitmap_Head.biWidth = cols;
|
||||
Bitmap_Head.biHeight = rows;
|
||||
Bitmap_Head.biPlanes = 1;
|
||||
Bitmap_Head.biBitCnt = BitsPerPixel;
|
||||
|
||||
if (encoded == 0)
|
||||
Bitmap_Head.biCompr = 0;
|
||||
else if (BitsPerPixel == 8)
|
||||
Bitmap_Head.biCompr = 1;
|
||||
else if (BitsPerPixel == 4)
|
||||
Bitmap_Head.biCompr = 2;
|
||||
else
|
||||
Bitmap_Head.biCompr = 0;
|
||||
|
||||
Bitmap_Head.biSizeIm = SpZeile * rows;
|
||||
|
||||
#ifdef GIMP_HAVE_RESOLUTION_INFO
|
||||
{
|
||||
double xresolution;
|
||||
double yresolution;
|
||||
gdouble xresolution;
|
||||
gdouble yresolution;
|
||||
gimp_image_get_resolution (image, &xresolution, &yresolution);
|
||||
|
||||
if (xresolution > 1e-5 && yresolution > 1e-5) {
|
||||
if (xresolution > GIMP_MIN_RESOLUTION &&
|
||||
yresolution > GIMP_MIN_RESOLUTION)
|
||||
{
|
||||
/*
|
||||
* xresolution and yresolution are in dots per inch.
|
||||
* the BMP spec says that biXPels and biYPels are in
|
||||
@ -222,12 +246,12 @@ WriteBMP (char *filename,
|
||||
Bitmap_Head.biXPels = 1;
|
||||
Bitmap_Head.biYPels = 1;
|
||||
#endif /* GIMP_HAVE_RESOLUTION_INFO */
|
||||
if (BitsPerPixel<24)
|
||||
Bitmap_Head.biClrUsed=colors;
|
||||
if (BitsPerPixel < 24)
|
||||
Bitmap_Head.biClrUsed = colors;
|
||||
else
|
||||
Bitmap_Head.biClrUsed=0;
|
||||
Bitmap_Head.biClrUsed = 0;
|
||||
|
||||
Bitmap_Head.biClrImp=Bitmap_Head.biClrUsed;
|
||||
Bitmap_Head.biClrImp = Bitmap_Head.biClrUsed;
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("\nSize: %u, Colors: %u, Bits: %u, Width: %u, Height: %u, Comp: %u, Zeile: %u\n",
|
||||
@ -236,135 +260,152 @@ WriteBMP (char *filename,
|
||||
#endif
|
||||
|
||||
/* And now write the header and the colormap (if any) to disk */
|
||||
|
||||
Write(outfile,"BM",2);
|
||||
|
||||
FromL(Bitmap_File_Head.bfSize,&puffer[0x00]);
|
||||
FromL(Bitmap_File_Head.reserverd,&puffer[0x04]);
|
||||
FromL(Bitmap_File_Head.bfOffs,&puffer[0x08]);
|
||||
FromL(Bitmap_File_Head.biSize,&puffer[0x0C]);
|
||||
Write (outfile, "BM", 2);
|
||||
|
||||
Write(outfile,puffer,16);
|
||||
FromL (Bitmap_File_Head.bfSize, &puffer[0x00]);
|
||||
FromL (Bitmap_File_Head.reserverd, &puffer[0x04]);
|
||||
FromL (Bitmap_File_Head.bfOffs, &puffer[0x08]);
|
||||
FromL (Bitmap_File_Head.biSize, &puffer[0x0C]);
|
||||
|
||||
FromL(Bitmap_Head.biWidth,&puffer[0x00]);
|
||||
FromL(Bitmap_Head.biHeight,&puffer[0x04]);
|
||||
FromS(Bitmap_Head.biPlanes,&puffer[0x08]);
|
||||
FromS(Bitmap_Head.biBitCnt,&puffer[0x0A]);
|
||||
FromL(Bitmap_Head.biCompr,&puffer[0x0C]);
|
||||
FromL(Bitmap_Head.biSizeIm,&puffer[0x10]);
|
||||
FromL(Bitmap_Head.biXPels,&puffer[0x14]);
|
||||
FromL(Bitmap_Head.biYPels,&puffer[0x18]);
|
||||
FromL(Bitmap_Head.biClrUsed,&puffer[0x1C]);
|
||||
FromL(Bitmap_Head.biClrImp,&puffer[0x20]);
|
||||
Write (outfile, puffer, 16);
|
||||
|
||||
FromL (Bitmap_Head.biWidth, &puffer[0x00]);
|
||||
FromL (Bitmap_Head.biHeight, &puffer[0x04]);
|
||||
FromS (Bitmap_Head.biPlanes, &puffer[0x08]);
|
||||
FromS (Bitmap_Head.biBitCnt, &puffer[0x0A]);
|
||||
FromL (Bitmap_Head.biCompr, &puffer[0x0C]);
|
||||
FromL (Bitmap_Head.biSizeIm, &puffer[0x10]);
|
||||
FromL (Bitmap_Head.biXPels, &puffer[0x14]);
|
||||
FromL (Bitmap_Head.biYPels, &puffer[0x18]);
|
||||
FromL (Bitmap_Head.biClrUsed, &puffer[0x1C]);
|
||||
FromL (Bitmap_Head.biClrImp, &puffer[0x20]);
|
||||
|
||||
Write (outfile, puffer, 36);
|
||||
WriteColorMap (outfile, Red, Green, Blue, MapSize);
|
||||
|
||||
Write(outfile,puffer,36);
|
||||
WriteColorMap(outfile,Red,Green,Blue,MapSize);
|
||||
|
||||
/* After that is done, we write the image ... */
|
||||
|
||||
WriteImage(outfile, pixels, cols, rows, encoded, channels, BitsPerPixel, SpZeile, MapSize);
|
||||
WriteImage (outfile,
|
||||
pixels, cols, rows,
|
||||
encoded, channels, BitsPerPixel, SpZeile, MapSize);
|
||||
|
||||
/* ... and exit normally */
|
||||
|
||||
fclose(outfile);
|
||||
gimp_drawable_detach(drawable);
|
||||
g_free(pixels);
|
||||
return TRUE;
|
||||
|
||||
fclose (outfile);
|
||||
gimp_drawable_detach (drawable);
|
||||
g_free (pixels);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
void
|
||||
WriteColorMap (FILE *f,
|
||||
int red[MAXCOLORS],
|
||||
int green[MAXCOLORS],
|
||||
int blue[MAXCOLORS],
|
||||
int size)
|
||||
gint red[MAXCOLORS],
|
||||
gint green[MAXCOLORS],
|
||||
gint blue[MAXCOLORS],
|
||||
gint size)
|
||||
{
|
||||
char trgb[4];
|
||||
int i;
|
||||
|
||||
size=size/4;
|
||||
trgb[3]=0;
|
||||
for (i=0;i<size;i++)
|
||||
gchar trgb[4];
|
||||
gint i;
|
||||
|
||||
size /= 4;
|
||||
trgb[3] = 0;
|
||||
for (i = 0; i < size; i++)
|
||||
{
|
||||
trgb[0]=(unsigned char) blue[i];
|
||||
trgb[1]=(unsigned char) green[i];
|
||||
trgb[2]=(unsigned char) red[i];
|
||||
Write(f,trgb,4);
|
||||
trgb[0] = (guchar) blue[i];
|
||||
trgb[1] = (guchar) green[i];
|
||||
trgb[2] = (guchar) red[i];
|
||||
Write (f, trgb, 4);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
WriteImage (FILE *f,
|
||||
guchar *src,
|
||||
int width,
|
||||
int height,
|
||||
int encoded,
|
||||
int channels,
|
||||
int bpp,
|
||||
int spzeile,
|
||||
int MapSize)
|
||||
gint width,
|
||||
gint height,
|
||||
gint encoded,
|
||||
gint channels,
|
||||
gint bpp,
|
||||
gint spzeile,
|
||||
gint MapSize)
|
||||
{
|
||||
guchar buf[16]={0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0};
|
||||
guchar puffer[8];
|
||||
guchar *temp,v;
|
||||
guchar *Zeile,*ketten;
|
||||
int xpos,ypos,i,j,rowstride,laenge,thiswidth;
|
||||
int breite, n, k;
|
||||
guchar *temp, v;
|
||||
guchar *Zeile, *ketten;
|
||||
gint xpos, ypos, i, j, rowstride, laenge, thiswidth;
|
||||
gint breite, n, k;
|
||||
|
||||
xpos = 0;
|
||||
rowstride = width * channels;
|
||||
|
||||
xpos=0;
|
||||
rowstride=width*channels;
|
||||
|
||||
/* We'll begin with the 24 bit Bitmaps, they are easy :-) */
|
||||
|
||||
if (bpp==24)
|
||||
|
||||
if (bpp == 24)
|
||||
{
|
||||
for (ypos=height-1;ypos>=0;ypos--) /* for each row */
|
||||
for (ypos = height - 1; ypos >= 0; ypos--) /* for each row */
|
||||
{
|
||||
for (i=0;i<width;i++) /* for each pixel */
|
||||
for (i = 0; i < width; i++) /* for each pixel */
|
||||
{
|
||||
temp = src + (ypos * rowstride) + (xpos * channels);
|
||||
buf[2]=(unsigned char) *temp;
|
||||
buf[2] = (guchar) *temp;
|
||||
temp++;
|
||||
buf[1]=(unsigned char) *temp;
|
||||
buf[1] = (guchar) *temp;
|
||||
temp++;
|
||||
buf[0]=(unsigned char) *temp;
|
||||
buf[0] = (guchar) *temp;
|
||||
xpos++;
|
||||
Write(f,buf,3);
|
||||
Write (f, buf, 3);
|
||||
}
|
||||
Write(f,&buf[3],spzeile-(width*3));
|
||||
Write (f, &buf[3], spzeile - (width * 3));
|
||||
|
||||
cur_progress++;
|
||||
if ((interactive_bmp) && ((cur_progress % 5) == 0)) gimp_progress_update ((double) cur_progress / (double) max_progress);
|
||||
xpos=0;
|
||||
if ((interactive_bmp) &&
|
||||
((cur_progress % 5) == 0))
|
||||
gimp_progress_update ((gdouble) cur_progress /
|
||||
(gdouble) max_progress);
|
||||
|
||||
xpos = 0;
|
||||
}
|
||||
} else {
|
||||
switch(encoded) /* now it gets more difficult */
|
||||
{ /* uncompressed 1,4 and 8 bit */
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (encoded) /* now it gets more difficult */
|
||||
{ /* uncompressed 1,4 and 8 bit */
|
||||
case 0:
|
||||
{
|
||||
thiswidth=(width/(8/bpp));
|
||||
if (width % (8/bpp)) thiswidth++;
|
||||
for (ypos=height-1;ypos>=0;ypos--) /* for each row */
|
||||
thiswidth = (width / (8 / bpp));
|
||||
if (width % (8 / bpp))
|
||||
thiswidth++;
|
||||
|
||||
for (ypos = height - 1; ypos >= 0; ypos--) /* for each row */
|
||||
{
|
||||
for (xpos=0;xpos<width;) /* for each _byte_ */
|
||||
for (xpos = 0; xpos < width;) /* for each _byte_ */
|
||||
{
|
||||
v=0;
|
||||
for (i=1;(i<=(8/bpp)) && (xpos<width);i++,xpos++) /* for each pixel */
|
||||
v = 0;
|
||||
for (i = 1;
|
||||
(i <= (8 / bpp)) && (xpos < width);
|
||||
i++, xpos++) /* for each pixel */
|
||||
{
|
||||
temp = src + (ypos * rowstride) + (xpos * channels);
|
||||
v=v | ((unsigned char) *temp << (8-(i*bpp)));
|
||||
v=v | ((guchar) *temp << (8 - (i * bpp)));
|
||||
}
|
||||
Write(f,&v,1);
|
||||
Write (f, &v, 1);
|
||||
}
|
||||
Write(f,&buf[3],spzeile-thiswidth);
|
||||
xpos=0;
|
||||
Write (f, &buf[3], spzeile - thiswidth);
|
||||
xpos = 0;
|
||||
|
||||
cur_progress++;
|
||||
if ((interactive_bmp) && ((cur_progress % 5) == 0))
|
||||
gimp_progress_update ((double) cur_progress / (double) max_progress);
|
||||
if ((interactive_bmp) &&
|
||||
((cur_progress % 5) == 0))
|
||||
gimp_progress_update ((gdouble) cur_progress /
|
||||
(gdouble) max_progress);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{ /* Save RLE encoded file, quite difficult */
|
||||
{ /* Save RLE encoded file, quite difficult */
|
||||
laenge = 0;
|
||||
buf[12] = 0;
|
||||
buf[13] = 1;
|
||||
@ -372,98 +413,126 @@ WriteImage (FILE *f,
|
||||
buf[15] = 0;
|
||||
Zeile = (guchar *) g_malloc (width / (8 / bpp) + 10);
|
||||
ketten = (guchar *) g_malloc (width / (8 / bpp) + 10);
|
||||
for (ypos = height - 1; ypos >= 0; ypos--) { /* each row separately */
|
||||
/*printf("Line: %i\n",ypos); */
|
||||
j = 0;
|
||||
/* first copy the pixels to a buffer, making one byte from two 4bit pixels */
|
||||
for (xpos = 0; xpos < width;) {
|
||||
v = 0;
|
||||
for (i = 1; (i <= (8 / bpp)) && (xpos < width); i++, xpos++) { /* for each pixel */
|
||||
temp = src + (ypos * rowstride) + (xpos * channels);
|
||||
v = v | ((guchar) * temp << (8 - (i * bpp)));
|
||||
}
|
||||
Zeile[j++] = v;
|
||||
}
|
||||
breite = width / (8 / bpp);
|
||||
if (width % (8 / bpp))
|
||||
breite++;
|
||||
/* then check for strings of equal bytes */
|
||||
for (i = 0; i < breite;) {
|
||||
for (ypos = height - 1; ypos >= 0; ypos--)
|
||||
{ /* each row separately */
|
||||
/*printf("Line: %i\n",ypos); */
|
||||
j = 0;
|
||||
while ((i + j < breite) && (j < (255 / (8 / bpp))) && (Zeile[i + j] == Zeile[i]))
|
||||
j++;
|
||||
ketten[i] = j;
|
||||
/*printf("%i:",ketten[i]); */
|
||||
i += j;
|
||||
}
|
||||
/*printf("\n"); */
|
||||
/* then write the strings and the other pixels to the file */
|
||||
for (i = 0; i < breite;) {
|
||||
if (ketten[i] < 3)
|
||||
/* strings of different pixels ... */
|
||||
/* first copy the pixels to a buffer,
|
||||
* making one byte from two 4bit pixels
|
||||
*/
|
||||
for (xpos = 0; xpos < width;)
|
||||
{
|
||||
v = 0;
|
||||
for (i = 1;
|
||||
(i <= (8 / bpp)) && (xpos < width);
|
||||
i++, xpos++)
|
||||
{ /* for each pixel */
|
||||
temp = src + (ypos * rowstride) + (xpos * channels);
|
||||
v = v | ((guchar) * temp << (8 - (i * bpp)));
|
||||
}
|
||||
Zeile[j++] = v;
|
||||
}
|
||||
breite = width / (8 / bpp);
|
||||
if (width % (8 / bpp))
|
||||
breite++;
|
||||
/* then check for strings of equal bytes */
|
||||
for (i = 0; i < breite;)
|
||||
{
|
||||
j = 0;
|
||||
while ((i + j < breite) && (j < (255 / (8 / bpp))) && (ketten[i + j] < 3))
|
||||
j += ketten[i + j];
|
||||
/* this can only happen if j jumps over the end with a 2 in ketten[i+j] */
|
||||
if (j > (255 / (8 / bpp)))
|
||||
j -= 2;
|
||||
/* 00 01 and 00 02 are reserved */
|
||||
if (j > 2) {
|
||||
Write (f, &buf[12], 1);
|
||||
n = j * (8 / bpp);
|
||||
if (n + i * (8 / bpp) > width)
|
||||
n--;
|
||||
Write (f, &n, 1);
|
||||
laenge += 2;
|
||||
Write (f, &Zeile[i], j);
|
||||
/*printf("0.%i.",n); */
|
||||
/*for (k=j;k;k--) printf("#"); */
|
||||
laenge += j;
|
||||
if ((j) % 2) {
|
||||
Write (f, &buf[12], 1);
|
||||
laenge++; /*printf("0"); */
|
||||
while ((i + j < breite) &&
|
||||
(j < (255 / (8 / bpp))) &&
|
||||
(Zeile[i + j] == Zeile[i]))
|
||||
j++;
|
||||
|
||||
ketten[i] = j;
|
||||
/*printf("%i:",ketten[i]); */
|
||||
i += j;
|
||||
}
|
||||
/*printf("\n"); */
|
||||
|
||||
/* then write the strings and the other pixels to the file */
|
||||
for (i = 0; i < breite;)
|
||||
{
|
||||
if (ketten[i] < 3)
|
||||
/* strings of different pixels ... */
|
||||
{
|
||||
j = 0;
|
||||
while ((i + j < breite) &&
|
||||
(j < (255 / (8 / bpp))) &&
|
||||
(ketten[i + j] < 3))
|
||||
j += ketten[i + j];
|
||||
|
||||
/* this can only happen if j jumps over
|
||||
* the end with a 2 in ketten[i+j]
|
||||
*/
|
||||
if (j > (255 / (8 / bpp)))
|
||||
j -= 2;
|
||||
/* 00 01 and 00 02 are reserved */
|
||||
if (j > 2)
|
||||
{
|
||||
Write (f, &buf[12], 1);
|
||||
n = j * (8 / bpp);
|
||||
if (n + i * (8 / bpp) > width)
|
||||
n--;
|
||||
Write (f, &n, 1);
|
||||
laenge += 2;
|
||||
Write (f, &Zeile[i], j);
|
||||
/*printf("0.%i.",n); */
|
||||
/*for (k=j;k;k--) printf("#"); */
|
||||
laenge += j;
|
||||
if ((j) % 2)
|
||||
{
|
||||
Write (f, &buf[12], 1);
|
||||
laenge++;
|
||||
/*printf("0"); */
|
||||
}
|
||||
/*printf("|"); */
|
||||
}
|
||||
else
|
||||
{
|
||||
for (k = i; k < i + j; k++)
|
||||
{
|
||||
n = (8 / bpp);
|
||||
if (n + i * (8 / bpp) > width)
|
||||
n--;
|
||||
Write (f, &n, 1);
|
||||
Write (f, &Zeile[k], 1);
|
||||
/*printf("%i.#|",n); */
|
||||
laenge += 2;
|
||||
}
|
||||
}
|
||||
i += j;
|
||||
}
|
||||
/*printf("|"); */
|
||||
} else {
|
||||
for (k = i; k < i + j; k++) {
|
||||
n = (8 / bpp);
|
||||
else
|
||||
/* strings of equal pixels */
|
||||
{
|
||||
n = ketten[i] * (8 / bpp);
|
||||
if (n + i * (8 / bpp) > width)
|
||||
n--;
|
||||
Write (f, &n, 1);
|
||||
Write (f, &Zeile[k], 1);
|
||||
Write (f, &Zeile[i], 1);
|
||||
/*printf("%i.#|",n); */
|
||||
i += ketten[i];
|
||||
laenge += 2;
|
||||
}
|
||||
}
|
||||
i += j;
|
||||
} else
|
||||
/* strings of equal pixels */
|
||||
{
|
||||
n = ketten[i] * (8 / bpp);
|
||||
if (n + i * (8 / bpp) > width)
|
||||
n--;
|
||||
Write (f, &n, 1);
|
||||
Write (f, &Zeile[i], 1);
|
||||
/*printf("%i.#|",n); */
|
||||
i += ketten[i];
|
||||
laenge += 2;
|
||||
}
|
||||
}
|
||||
/*printf("\n"); */
|
||||
Write (f, &buf[14], 2); /* End of row */
|
||||
laenge += 2;
|
||||
cur_progress++;
|
||||
if ((interactive_bmp) && ((cur_progress % 5) == 0))
|
||||
gimp_progress_update ((double)cur_progress / max_progress);
|
||||
}
|
||||
fseek (f, -2, SEEK_CUR); /* Overwrite last End of row ... */
|
||||
Write (f, &buf[12], 2); /* ... with End of file */
|
||||
}
|
||||
/*printf("\n"); */
|
||||
Write (f, &buf[14], 2); /* End of row */
|
||||
laenge += 2;
|
||||
|
||||
fseek (f, 0x22, SEEK_SET); /* Write length of image */
|
||||
cur_progress++;
|
||||
if ((interactive_bmp) &&
|
||||
((cur_progress % 5) == 0))
|
||||
gimp_progress_update ((gdouble) cur_progress /
|
||||
(gdouble) max_progress);
|
||||
}
|
||||
fseek (f, -2, SEEK_CUR); /* Overwrite last End of row ... */
|
||||
Write (f, &buf[12], 2); /* ... with End of file */
|
||||
|
||||
fseek (f, 0x22, SEEK_SET); /* Write length of image */
|
||||
FromL (laenge, puffer);
|
||||
Write (f, puffer, 4);
|
||||
fseek (f, 0x02, SEEK_SET); /* Write length of file */
|
||||
fseek (f, 0x02, SEEK_SET); /* Write length of file */
|
||||
laenge += (0x36 + MapSize);
|
||||
FromL (laenge, puffer);
|
||||
Write (f, puffer, 4);
|
||||
@ -473,67 +542,47 @@ WriteImage (FILE *f,
|
||||
}
|
||||
}
|
||||
}
|
||||
if (interactive_bmp) gimp_progress_update(1);
|
||||
if (interactive_bmp)
|
||||
gimp_progress_update (1);
|
||||
}
|
||||
|
||||
|
||||
/* These ones are just copied from the GIF-plugin */
|
||||
|
||||
static gint
|
||||
save_dialog ()
|
||||
save_dialog (void)
|
||||
{
|
||||
GtkWidget *dlg;
|
||||
GtkWidget *button;
|
||||
GtkWidget *hbbox;
|
||||
GtkWidget *toggle;
|
||||
GtkWidget *frame;
|
||||
GtkWidget *vbox;
|
||||
|
||||
dlg = gtk_dialog_new ();
|
||||
gtk_window_set_title (GTK_WINDOW (dlg), _("Save as BMP"));
|
||||
gtk_window_position (GTK_WINDOW (dlg), GTK_WIN_POS_MOUSE);
|
||||
dlg = gimp_dialog_new (_("Save as BMP"), "bmp",
|
||||
gimp_plugin_help_func, "filters/bmp.html",
|
||||
GTK_WIN_POS_MOUSE,
|
||||
FALSE, TRUE, FALSE,
|
||||
|
||||
_("OK"), save_ok_callback,
|
||||
NULL, NULL, NULL, TRUE, FALSE,
|
||||
_("Cancel"), gtk_widget_destroy,
|
||||
NULL, 1, NULL, FALSE, TRUE,
|
||||
|
||||
NULL);
|
||||
|
||||
gtk_signal_connect (GTK_OBJECT (dlg), "destroy",
|
||||
(GtkSignalFunc) save_close_callback,
|
||||
GTK_SIGNAL_FUNC (gtk_main_quit),
|
||||
NULL);
|
||||
|
||||
/* Action area */
|
||||
gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dlg)->action_area), 2);
|
||||
gtk_box_set_homogeneous (GTK_BOX (GTK_DIALOG (dlg)->action_area), FALSE);
|
||||
hbbox = gtk_hbutton_box_new ();
|
||||
gtk_button_box_set_spacing (GTK_BUTTON_BOX (hbbox), 4);
|
||||
gtk_box_pack_end (GTK_BOX (GTK_DIALOG (dlg)->action_area), hbbox, FALSE, FALSE, 0);
|
||||
gtk_widget_show (hbbox);
|
||||
|
||||
button = gtk_button_new_with_label (_("OK"));
|
||||
GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
|
||||
gtk_signal_connect (GTK_OBJECT (button), "clicked",
|
||||
(GtkSignalFunc) save_ok_callback,
|
||||
dlg);
|
||||
gtk_box_pack_start (GTK_BOX (hbbox), button, FALSE, FALSE, 0);
|
||||
gtk_widget_grab_default (button);
|
||||
gtk_widget_show (button);
|
||||
|
||||
button = gtk_button_new_with_label (_("Cancel"));
|
||||
GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
|
||||
gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
|
||||
(GtkSignalFunc) gtk_widget_destroy,
|
||||
GTK_OBJECT (dlg));
|
||||
gtk_box_pack_start (GTK_BOX (hbbox), button, FALSE, FALSE, 0);
|
||||
gtk_widget_show (button);
|
||||
|
||||
/* parameter settings */
|
||||
frame = gtk_frame_new (_("Save Options"));
|
||||
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_ETCHED_IN);
|
||||
gtk_container_border_width (GTK_CONTAINER (frame), 4);
|
||||
gtk_container_border_width (GTK_CONTAINER (frame), 6);
|
||||
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlg)->vbox), frame, TRUE, TRUE, 0);
|
||||
vbox = gtk_vbox_new (FALSE, 4);
|
||||
|
||||
vbox = gtk_vbox_new (FALSE, 2);
|
||||
gtk_container_border_width (GTK_CONTAINER (vbox), 4);
|
||||
gtk_container_add (GTK_CONTAINER (frame), vbox);
|
||||
|
||||
toggle = gtk_check_button_new_with_label (_("RLE encoded"));
|
||||
gtk_box_pack_start (GTK_BOX (vbox), toggle, TRUE, TRUE, 0);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), toggle, FALSE, FALSE, 0);
|
||||
gtk_signal_connect (GTK_OBJECT (toggle), "toggled",
|
||||
(GtkSignalFunc) save_toggle_update,
|
||||
GTK_SIGNAL_FUNC (gimp_toggle_button_update),
|
||||
&encoded);
|
||||
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), encoded);
|
||||
gtk_widget_show (toggle);
|
||||
@ -544,34 +593,15 @@ save_dialog ()
|
||||
|
||||
gtk_main ();
|
||||
gdk_flush ();
|
||||
|
||||
return gsint.run;
|
||||
}
|
||||
|
||||
static void
|
||||
save_close_callback (GtkWidget *widget,
|
||||
gpointer data)
|
||||
{
|
||||
gtk_main_quit ();
|
||||
}
|
||||
|
||||
static void
|
||||
save_ok_callback (GtkWidget *widget,
|
||||
gpointer data)
|
||||
{
|
||||
gsint.run = TRUE;
|
||||
|
||||
gtk_widget_destroy (GTK_WIDGET (data));
|
||||
}
|
||||
|
||||
static void
|
||||
save_toggle_update (GtkWidget *widget,
|
||||
gpointer data)
|
||||
{
|
||||
int *toggle_val;
|
||||
|
||||
toggle_val = (int *) data;
|
||||
|
||||
if (GTK_TOGGLE_BUTTON (widget)->active)
|
||||
*toggle_val = TRUE;
|
||||
else
|
||||
*toggle_val = FALSE;
|
||||
}
|
||||
|
Reference in New Issue
Block a user