]> Pileus Git - ~andy/gtk/blob - gdk-pixbuf/io-ras.c
third patch. Now it seems to load.
[~andy/gtk] / gdk-pixbuf / io-ras.c
1 /* GdkPixbuf library - SUNRAS image loader
2  *
3  * Copyright (C) 1999 The Free Software Foundation
4  *
5  * Authors: Arjan van de Ven <arjan@fenrus.demon.nl>
6  *          Federico Mena-Quintero <federico@gimp.org>
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Library General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Library General Public License for more details.
17  *
18  * You should have received a copy of the GNU Library General Public
19  * License along with this library; if not, write to the
20  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21  * Boston, MA 02111-1307, USA.
22  */
23
24 #include <config.h>
25 #include <stdio.h>
26 #include <glib.h>
27 #include "gdk-pixbuf.h"
28 #include "gdk-pixbuf-io.h"
29 \f
30
31
32 /* 
33    Header structure for sunras files.
34    All values are in big-endian order on disk
35  */
36
37 struct rasterfile {
38         guint magic;
39         guint width;
40         guint height;
41         guint depth;
42         guint length;
43         guint type;
44         guint maptype;
45         guint maplength;
46 };
47
48 /* 
49         This does a byte-order swap. Does glib have something like
50         be32_to_cpu() ??
51 */
52
53 unsigned int ByteOrder(unsigned int i)
54 {
55         unsigned int i2;
56         i2 =
57             ((i & 255) << 24) | (((i >> 8) & 255) << 16) |
58             (((i >> 16) & 255) << 8) | ((i >> 24) & 255);
59         return i2;
60 }
61
62 /* 
63         Destroy notification function for the libart pixbuf 
64 */
65
66 static void free_buffer(gpointer user_data, gpointer data)
67 {
68         free(data);
69 }
70
71 /*
72
73 OneLineBGR does what it says: Reads one line from file.
74 Note: It also changes BGR pixelorder to RGB as libart currently
75 doesn't support ART_PIX_BGR.
76
77 */
78 static OneLineBGR(FILE * f, guint Width, guchar * pixels, gint bpp)
79 {
80         gint result, X;
81         guchar DummyByte;
82
83         result = fread(pixels, 1, Width * bpp, f);
84
85         g_assert(result == Width * bpp);
86         if (((Width * bpp) & 7) != 0)   /*  Not 16 bit aligned */
87                 fread(&DummyByte, 1, 1, f);
88         X = 0;
89         while (X < Width) {
90                 guchar Blue;
91                 Blue = pixels[X * bpp];
92                 pixels[X * bpp] = pixels[X * bpp + 2];
93                 pixels[X * bpp + 2] = Blue;
94                 X++;
95         }
96 }
97
98 /* Shared library entry point */
99 GdkPixbuf *image_load(FILE * f)
100 {
101         gint i, bpp, Y;
102         guchar *pixels;
103         struct rasterfile Header;
104
105         i = fread(&Header, 1, sizeof(Header), f);
106         g_assert(i == 32);
107
108         /* Correct the byteorder of the header here */
109         Header.width = ByteOrder(Header.width);
110         Header.height = ByteOrder(Header.height);
111         Header.depth = ByteOrder(Header.depth);
112         Header.length = ByteOrder(Header.length);
113         Header.type = ByteOrder(Header.type);
114         Header.maptype = ByteOrder(Header.maptype);
115         Header.maplength = ByteOrder(Header.maplength);
116
117
118         bpp = 0;
119         if (Header.depth == 32)
120                 bpp = 4;
121         else
122                 bpp = 3;
123
124         g_assert(bpp != 0);     /* Only 24 and 32 bpp for now */
125
126         pixels = (guchar *) malloc(Header.width * Header.height * bpp);
127         if (!pixels) {
128                 return NULL;
129         }
130
131         /* 
132
133            Loop through the file, one line at a time. 
134            Only BGR-style files are handled right now.
135
136          */
137         Y = 0;
138         while (Y < Header.height) {
139                 OneLineBGR(f, Header.width,
140                            &pixels[Y * Header.width * bpp], bpp);
141                 Y++;
142         }
143
144
145         if (bpp == 4)
146                 return gdk_pixbuf_new_from_data(pixels, ART_PIX_RGB, TRUE,
147                                                 Header.width,
148                                                 Header.height,
149                                                 Header.width * bpp,
150                                                 free_buffer, NULL);
151         else
152                 return gdk_pixbuf_new_from_data(pixels, ART_PIX_RGB, FALSE,
153                                                 Header.width,
154                                                 Header.height,
155                                                 Header.width * bpp,
156                                                 free_buffer, NULL);
157 }