1999-08-17 08:59:07 +08:00
|
|
|
#include "config.h"
|
|
|
|
|
|
|
|
#include <math.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <errno.h>
|
|
|
|
|
|
|
|
#include "appenv.h"
|
|
|
|
#include "brush_header.h"
|
|
|
|
#include "pattern_header.h"
|
|
|
|
#include "gimpbrush.h"
|
|
|
|
#include "gimpbrushpixmap.h"
|
|
|
|
#include "gimpbrushlist.h"
|
|
|
|
|
|
|
|
#include "paint_core.h"
|
|
|
|
#include "gimprc.h"
|
|
|
|
#include "gimpbrushhose.h"
|
|
|
|
|
|
|
|
static void
|
|
|
|
gimp_brush_hose_generate(GimpBrushHose *brush);
|
|
|
|
|
|
|
|
static GimpObjectClass* parent_class;
|
|
|
|
|
|
|
|
static void
|
|
|
|
gimp_brush_hose_destroy(GtkObject *object)
|
|
|
|
{
|
|
|
|
GTK_OBJECT_CLASS(parent_class)->destroy (object);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gimp_brush_hose_class_init (GimpBrushHoseClass *klass)
|
|
|
|
{
|
|
|
|
GtkObjectClass *object_class;
|
|
|
|
|
|
|
|
object_class = GTK_OBJECT_CLASS(klass);
|
|
|
|
|
|
|
|
parent_class = gtk_type_class (GIMP_TYPE_BRUSH_PIXMAP);
|
|
|
|
object_class->destroy = gimp_brush_hose_destroy;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
gimp_brush_hose_init(GimpBrushHose *brush)
|
|
|
|
{
|
|
|
|
brush->name = NULL;
|
|
|
|
brush->filename = NULL;
|
|
|
|
brush->brush_list = gimp_brush_list_new();
|
|
|
|
}
|
|
|
|
|
|
|
|
GtkType gimp_brush_hose_get_type(void)
|
|
|
|
{
|
|
|
|
static GtkType type=0;
|
|
|
|
if(!type){
|
|
|
|
GtkTypeInfo info={
|
|
|
|
"GimpBrushHose",
|
|
|
|
sizeof(GimpBrushHose),
|
|
|
|
sizeof(GimpBrushHoseClass),
|
|
|
|
(GtkClassInitFunc)gimp_brush_hose_class_init,
|
|
|
|
(GtkObjectInitFunc)gimp_brush_hose_init,
|
|
|
|
/* reserved_1 */ NULL,
|
|
|
|
/* reserver_2 */ NULL,
|
|
|
|
(GtkClassInitFunc) NULL};
|
|
|
|
type=gtk_type_unique(GIMP_TYPE_BRUSH_PIXMAP, &info);
|
|
|
|
}
|
|
|
|
return type;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
GimpBrushHose *
|
|
|
|
gimp_brush_hose_load (char *file_name)
|
|
|
|
{
|
|
|
|
GimpBrushHose *hose;
|
|
|
|
GimpBrushPixmap *brush;
|
|
|
|
GimpBrushList *list;
|
1999-08-18 07:32:48 +08:00
|
|
|
GimpObject o;
|
1999-08-17 08:59:07 +08:00
|
|
|
FILE *fp;
|
|
|
|
unsigned char buf[sz_BrushHeader];
|
|
|
|
gchar buf2[1024];
|
|
|
|
BrushHeader header;
|
|
|
|
int bn_size;
|
|
|
|
unsigned int *hp;
|
|
|
|
int i;
|
|
|
|
int num_of_brushes;
|
|
|
|
int brush_count=0;
|
|
|
|
|
|
|
|
hose = GIMP_BRUSH_HOSE(gimp_type_new(gimp_brush_hose_get_type()));
|
|
|
|
GIMP_BRUSH_HOSE(hose)->filename = g_strdup(file_name);
|
|
|
|
|
Actually use the enum types GimpImageType, GimpImageBaseType,
* app/*.[ch]: Actually use the enum types GimpImageType,
GimpImageBaseType, LayerModeEffects, PaintApplicationMode,
BrushApplicationMode, GimpFillType and ConvertPaletteType, instead
of just int or gint. Hopefully I catched most of the places
where these should be used.
Add an enum ConvolutionType, suffix the too general constants
NORMAL, ABSOLUTE and NEGATIVE with _CONVOL. Use NORMAL_MODE
instead of NORMAL in some places (this was what was intended). Fix
some minor gccisms.
* app/apptypes.h: New file. This file contains the above
enumeration types, and some opaque struct typedefs. It was
necessary to collect these in one header that doesn't include
other headers, because when we started using the above mentioned
types in the headers, all hell broke loose because of the
spaghetti-like cross-inclusion mess between headers.
(An example: Header A includes header B, which includes header C
which includes A. B uses a type defined in A. This is not defined,
because A hasn't defined it yet at the point where it includes B,
and A included from B of course is skipped as we already are
reading A.)
1999-08-19 07:41:39 +08:00
|
|
|
brush = GIMP_BRUSH_PIXMAP (hose);
|
1999-08-17 08:59:07 +08:00
|
|
|
|
|
|
|
list = gimp_brush_list_new();
|
|
|
|
|
1999-08-18 07:32:48 +08:00
|
|
|
printf("opening hose: %s\n", file_name);
|
1999-08-17 08:59:07 +08:00
|
|
|
|
1999-08-18 07:32:48 +08:00
|
|
|
if ((fp = fopen(file_name, "rb")) == NULL)
|
1999-08-17 08:59:07 +08:00
|
|
|
return NULL;
|
|
|
|
|
|
|
|
/* the file format starts with a painfully simple text header
|
|
|
|
and we use a painfully simple way to read it */
|
|
|
|
if(fgets (buf2, 1024, fp) == NULL)
|
|
|
|
return NULL;
|
|
|
|
buf2[strlen(buf2) - 1] = '\0';
|
|
|
|
hose->name = g_strdup(buf2);
|
|
|
|
|
|
|
|
if(fgets (buf2, 1024, fp) == NULL)
|
|
|
|
return NULL;
|
|
|
|
//buf2[strlen(buf2) - 1] = '\0';
|
|
|
|
num_of_brushes = strtol(buf2,NULL,10);
|
|
|
|
|
|
|
|
/* get the number of brushes */
|
|
|
|
|
|
|
|
printf("filename: %s \n name: %s number: %i \n",hose->filename, hose->name, num_of_brushes);
|
|
|
|
|
|
|
|
|
|
|
|
/* FIXME
|
|
|
|
|
|
|
|
Think i need to flesh out all the bits if this thing is
|
|
|
|
going to stop segfaulting
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
while(brush_count < num_of_brushes)
|
|
|
|
{
|
|
|
|
|
|
|
|
/* we read in the brush mask first */
|
|
|
|
|
|
|
|
/* Read in the header size */
|
|
|
|
if ((fread (buf, 1, sz_BrushHeader, fp)) < sz_BrushHeader)
|
|
|
|
{
|
|
|
|
fclose (fp);
|
1999-08-18 07:32:48 +08:00
|
|
|
gimp_object_destroy (hose);
|
1999-08-17 08:59:07 +08:00
|
|
|
gimp_object_destroy (brush);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
1999-08-18 07:32:48 +08:00
|
|
|
if (brush_count > 0)
|
|
|
|
brush = GIMP_BRUSH_PIXMAP(gimp_type_new(gimp_brush_pixmap_get_type()));
|
|
|
|
GIMP_BRUSH(brush)->filename = g_strdup(file_name);
|
|
|
|
|
1999-08-17 08:59:07 +08:00
|
|
|
/* rearrange the bytes in each unsigned int */
|
|
|
|
hp = (unsigned int *) &header;
|
|
|
|
for (i = 0; i < (sz_BrushHeader / 4); i++)
|
|
|
|
hp [i] = (buf [i * 4] << 24) + (buf [i * 4 + 1] << 16) +
|
|
|
|
(buf [i * 4 + 2] << 8) + (buf [i * 4 + 3]);
|
|
|
|
|
|
|
|
|
|
|
|
/* Check for correct file format */
|
|
|
|
if (header.magic_number != GBRUSH_MAGIC)
|
|
|
|
{
|
|
|
|
/* One thing that can save this error is if the brush is version 1 */
|
|
|
|
if (header.version != 1)
|
|
|
|
{
|
|
|
|
fclose (fp);
|
1999-08-18 07:32:48 +08:00
|
|
|
gimp_object_destroy (hose);
|
1999-08-17 08:59:07 +08:00
|
|
|
gimp_object_destroy (brush);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (header.version == 1)
|
|
|
|
{
|
|
|
|
/* If this is a version 1 brush, set the fp back 8 bytes */
|
|
|
|
fseek (fp, -8, SEEK_CUR);
|
|
|
|
header.header_size += 8;
|
|
|
|
/* spacing is not defined in version 1 */
|
|
|
|
header.spacing = 25;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Read in the brush name */
|
|
|
|
if ((bn_size = (header.header_size - sz_BrushHeader)))
|
|
|
|
{
|
|
|
|
GIMP_BRUSH(brush)->name = (char *) g_malloc (sizeof (char) * bn_size);
|
|
|
|
if ((fread (GIMP_BRUSH(brush)->name, 1, bn_size, fp)) < bn_size)
|
|
|
|
{
|
|
|
|
g_message ("Error in GIMP brush file...aborting.");
|
|
|
|
fclose (fp);
|
1999-08-18 07:32:48 +08:00
|
|
|
gimp_object_destroy (hose);
|
1999-08-17 08:59:07 +08:00
|
|
|
gimp_object_destroy (brush);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
switch(header.version)
|
|
|
|
{
|
|
|
|
|
|
|
|
case 1:
|
|
|
|
case 2:
|
|
|
|
/* Get a new brush mask */
|
|
|
|
GIMP_BRUSH(brush)->mask = temp_buf_new (header.width,
|
|
|
|
header.height,
|
|
|
|
header.bytes,
|
|
|
|
0, 0, NULL);
|
1999-08-19 13:22:45 +08:00
|
|
|
|
|
|
|
GIMP_BRUSH(brush)->spacing = header.spacing;
|
|
|
|
/* set up spacing axis */
|
|
|
|
GIMP_BRUSH(brush)->x_axis.x = header.width / 2.0;
|
|
|
|
GIMP_BRUSH(brush)->x_axis.y = 0.0;
|
|
|
|
GIMP_BRUSH(brush)->y_axis.x = 0.0;
|
|
|
|
GIMP_BRUSH(brush)->y_axis.y = header.height / 2.0;
|
1999-08-17 08:59:07 +08:00
|
|
|
/* Read the brush mask data */
|
|
|
|
|
|
|
|
if ((fread (temp_buf_data (GIMP_BRUSH(brush)->mask),
|
|
|
|
1,header.width * header.height,
|
|
|
|
fp)) < header.width * header.height)
|
|
|
|
g_message ("GIMP brush file appears to be truncated.");
|
|
|
|
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
g_message ("Unknown brush format version #%d in \"%s\"\n",
|
|
|
|
header.version, file_name);
|
|
|
|
|
|
|
|
fclose (fp);
|
1999-08-18 07:32:48 +08:00
|
|
|
gimp_object_destroy (hose);
|
1999-08-17 08:59:07 +08:00
|
|
|
gimp_object_destroy (brush);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* PATTERN STUFF HERE */
|
|
|
|
/* Read in the header size */
|
|
|
|
if ((fread (buf, 1, sz_PatternHeader, fp)) < sz_PatternHeader)
|
|
|
|
{
|
|
|
|
fclose (fp);
|
1999-08-18 07:32:48 +08:00
|
|
|
gimp_object_destroy (hose);
|
|
|
|
gimp_object_destroy (brush);
|
1999-08-17 08:59:07 +08:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
hp = (unsigned int *) &header;
|
|
|
|
for (i = 0; i < (sz_PatternHeader / 4); i++)
|
|
|
|
hp [i] = (buf [i * 4] << 24) + (buf [i * 4 + 1] << 16) +
|
|
|
|
(buf [i * 4 + 2] << 8) + (buf [i * 4 + 3]);
|
|
|
|
|
|
|
|
|
|
|
|
brush->pixmap_mask = temp_buf_new (header.width,
|
|
|
|
header.height,
|
|
|
|
header.bytes,
|
|
|
|
0, 0, NULL);
|
|
|
|
|
|
|
|
|
1999-08-18 07:32:48 +08:00
|
|
|
/* Skip the pattern name */
|
1999-08-17 08:59:07 +08:00
|
|
|
if ((bn_size = (header.header_size - sz_PatternHeader)))
|
1999-08-18 07:32:48 +08:00
|
|
|
if ((fseek (fp, bn_size, SEEK_CUR)) < 0)
|
|
|
|
{
|
|
|
|
g_message ("Error in GIMP pattern file...aborting.");
|
|
|
|
fclose (fp);
|
|
|
|
gimp_object_destroy (hose);
|
|
|
|
gimp_object_destroy (brush);
|
|
|
|
return NULL;
|
|
|
|
}
|
1999-08-17 08:59:07 +08:00
|
|
|
|
|
|
|
if ((fread (temp_buf_data (brush->pixmap_mask), 1,
|
|
|
|
header.width * header.height * header.bytes, fp))
|
|
|
|
< header.width * header.height * header.bytes)
|
|
|
|
g_message ("GIMP pattern file appears to be truncated.");
|
|
|
|
|
|
|
|
|
1999-08-18 07:32:48 +08:00
|
|
|
gimp_brush_list_add(list,GIMP_BRUSH(brush));
|
1999-08-17 08:59:07 +08:00
|
|
|
|
|
|
|
printf("got here brush_count: %i\n", brush_count);
|
|
|
|
printf("brush_list_count: %i \n", gimp_brush_list_length(list));
|
|
|
|
|
|
|
|
|
|
|
|
brush_count++;
|
|
|
|
printf("brush index is: %i \n", gimp_brush_list_get_brush_index(list, GIMP_BRUSH(brush)));
|
|
|
|
}
|
|
|
|
|
|
|
|
fclose (fp);
|
1999-08-18 07:32:48 +08:00
|
|
|
|
|
|
|
if (!GIMP_IS_BRUSH_HOSE(hose))
|
|
|
|
g_print ("Is not BRUSH_HOSE???\n");
|
|
|
|
#if 0
|
|
|
|
brush = GIMP_BRUSH_PIXMAP((gimp_brush_list_get_brush_by_index(list,0)));
|
1999-08-17 08:59:07 +08:00
|
|
|
hose->pixmap_brush = *brush;
|
1999-08-18 07:32:48 +08:00
|
|
|
#endif
|
1999-08-17 08:59:07 +08:00
|
|
|
hose->brush_list = list;
|
|
|
|
/* random test code */
|
|
|
|
|
|
|
|
printf("got here, return hose;\n");
|
|
|
|
return hose;
|
|
|
|
|
|
|
|
}
|