root/OpenSceneGraph/trunk/src/osgPlugins/pic/ReaderWriterPIC.cpp @ 13041

Revision 13041, 6.6 kB (checked in by robert, 2 years ago)

Ran script to remove trailing spaces and tabs

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1#include <osg/Image>
2#include <osg/Notify>
3#include <osg/Geode>
4#include <osg/GL>
5
6#include <osgDB/Registry>
7#include <osgDB/FileNameUtils>
8#include <osgDB/FileUtils>
9
10/****************************************************************************
11 *
12 * Follows is code extracted from the simage library.  Original Authors:
13 *
14 *      Systems in Motion,
15 *      <URL:http://www.sim.no>
16 *
17 *      Peder Blekken <pederb@sim.no>
18 *      Morten Eriksen <mortene@sim.no>
19 *      Marius Bugge Monsen <mariusbu@sim.no>
20 *
21 * The original COPYING notice
22 *
23 *      All files in this library are public domain, except simage_rgb.cpp which is
24 *      Copyright (c) Mark J Kilgard <mjk@nvidia.com>. I will contact Mark
25 *      very soon to hear if this source also can become public domain.
26 *
27 *      Please send patches for bugs and new features to: <pederb@sim.no>.
28 *
29 *      Peder Blekken
30 *
31 *
32 * Ported into the OSG as a plugin, Robert Osfield Decemeber 2000.
33 * Note, reference above to license of simage_rgb is not relevent to the OSG
34 * as the OSG does not use it.  Also for patches, bugs and new features
35 * please send them direct to the OSG dev team rather than address above.
36 *
37 **********************************************************************/
38
39#include <stdio.h>
40#include <string.h>
41#include <stdlib.h>
42
43#define ERROR_NO_ERROR         0
44#define ERROR_READING_HEADER   1
45#define ERROR_READING_PALETTE  2
46#define ERROR_MEMORY           3
47#define ERROR_READ_ERROR       4
48
49static int picerror = ERROR_NO_ERROR;
50
51int
52simage_pic_error(char *buffer, int bufferlen)
53{
54    switch (picerror)
55    {
56        case ERROR_READING_HEADER:
57            strncpy(buffer, "PIC loader: Error reading header", bufferlen);
58            break;
59        case ERROR_READING_PALETTE:
60            strncpy(buffer, "PIC loader: Error reading palette", bufferlen);
61            break;
62        case ERROR_MEMORY:
63            strncpy(buffer, "PIC loader: Out of memory error", bufferlen);
64            break;
65        case ERROR_READ_ERROR:
66            strncpy(buffer, "PIC loader: Read error", bufferlen);
67            break;
68    }
69    return picerror;
70}
71
72
73/* byte order workaround *sigh* */
74
75static int
76readint16(FILE *fp, int * res)
77{
78    unsigned char tmp = 0;
79    unsigned int tmp2;
80    if (fread(&tmp, 1, 1, fp) != 1) return 0;
81    *res = tmp;
82    if (fread(&tmp, 1, 1, fp) != 1) return 0;
83    tmp2 = tmp;
84    tmp2 <<= 8;
85    *res |= tmp2;
86    return 1;
87}
88
89
90int
91simage_pic_identify(const char *, const unsigned char *header, int headerlen)
92{
93    static unsigned char piccmp[] = {0x19, 0x91};
94    if (headerlen < 2) return 0;
95    if (memcmp((const void*)header,
96        (const void*)piccmp, 2) == 0) return 1;
97    return 0;
98}
99
100
101unsigned char *
102simage_pic_load(const char *filename,
103int *width_ret,
104int *height_ret,
105int *numComponents_ret)
106{
107    int w, h, width, height, i, j, format;
108    unsigned char palette[256][3];
109    unsigned char * tmpbuf, * buffer, * ptr;
110
111    FILE *fp = osgDB::fopen(filename, "rb");
112    if (!fp) return NULL;
113
114    picerror = ERROR_NO_ERROR;
115
116    fseek(fp, 2, SEEK_SET);
117    if (!readint16(fp, &w))
118    {
119        picerror = ERROR_READING_HEADER;
120        fclose(fp);
121        return NULL;
122    }
123
124    fseek(fp, 4, SEEK_SET);
125    if (!readint16(fp, &h))
126    {
127        picerror = ERROR_READING_HEADER;
128        fclose(fp);
129        return NULL;
130    }
131
132    width = w;
133    height = h;
134
135    if (width <= 0 || height <= 0)
136    {
137        fclose(fp);
138        return NULL;
139    }
140    fseek(fp, 32, SEEK_SET);
141
142    if (fread(&palette, 3, 256, fp) != 256)
143    {
144        picerror = ERROR_READING_PALETTE;
145    }
146
147    tmpbuf = new unsigned char [width];
148    buffer = new unsigned char [3*width*height];
149    if (tmpbuf == NULL || buffer == NULL)
150    {
151        picerror = ERROR_MEMORY;
152        if (tmpbuf) delete [] tmpbuf;
153        if (buffer) delete [] buffer;
154        fclose(fp);
155        return NULL;
156    }
157    ptr = buffer;
158    for (i = 0; i < height; i++)
159    {
160        if (fread(tmpbuf, 1, width, fp) != (size_t) width)
161        {
162            picerror = ERROR_READ_ERROR;
163            fclose(fp);
164            if (tmpbuf) delete [] tmpbuf;
165            if (buffer) delete [] buffer;
166            buffer = NULL;
167            width = height = 0;
168            return NULL;
169        }
170        for (j = 0; j < width; j++)
171        {
172            int idx = tmpbuf[j];
173            *ptr++ = palette[idx][0];
174            *ptr++ = palette[idx][1];
175            *ptr++ = palette[idx][2];
176        }
177    }
178    format = 3;
179    fclose(fp);
180
181    *width_ret = width;
182    *height_ret = height;
183    *numComponents_ret = format;
184
185    if (tmpbuf) delete [] tmpbuf;
186
187    return buffer;
188}
189
190
191class ReaderWriterPIC : public osgDB::ReaderWriter
192{
193    public:
194        ReaderWriterPIC()
195        {
196            supportsExtension("pic","PIC Image format");
197        }
198
199        virtual const char* className() const { return "PIC Image Reader"; }
200
201        virtual ReadResult readObject(const std::string& file, const osgDB::ReaderWriter::Options* options =NULL) const
202        {
203            return readImage(file, options);
204        }
205
206        virtual ReadResult readImage(const std::string& file, const osgDB::ReaderWriter::Options* options) const
207        {
208            std::string ext = osgDB::getLowerCaseFileExtension(file);
209            if (!acceptsExtension(ext)) return ReadResult::FILE_NOT_HANDLED;
210
211            std::string fileName = osgDB::findDataFile( file, options );
212            if (fileName.empty()) return ReadResult::FILE_NOT_FOUND;
213
214            unsigned char *imageData = NULL;
215            int width_ret;
216            int height_ret;
217            int numComponents_ret;
218
219            imageData = simage_pic_load(fileName.c_str(),&width_ret,&height_ret,&numComponents_ret);
220
221            if (imageData==NULL) return ReadResult::FILE_NOT_HANDLED;
222
223            int s = width_ret;
224            int t = height_ret;
225            int r = 1;
226
227            int internalFormat = numComponents_ret;
228
229            unsigned int pixelFormat =
230                numComponents_ret == 1 ? GL_LUMINANCE :
231            numComponents_ret == 2 ? GL_LUMINANCE_ALPHA :
232            numComponents_ret == 3 ? GL_RGB :
233            numComponents_ret == 4 ? GL_RGBA : (GLenum)-1;
234
235            unsigned int dataType = GL_UNSIGNED_BYTE;
236
237            osg::Image* pOsgImage = new osg::Image;
238            pOsgImage->setFileName(fileName.c_str());
239            pOsgImage->setImage(s,t,r,
240                internalFormat,
241                pixelFormat,
242                dataType,
243                imageData,
244                osg::Image::USE_NEW_DELETE);
245
246            return pOsgImage;
247
248        }
249};
250
251// now register with Registry to instantiate the above
252// reader/writer.
253REGISTER_OSGPLUGIN(pic, ReaderWriterPIC)
Note: See TracBrowser for help on using the browser.