r915:
[cinelerra_cv/mob.git] / cinelerra / filegif.C
blobda1759a4d4ac2ed0a3af0226b72bc14e20e98609
1 #include "assets.h"
2 #include "file.h"
3 #include "filetiff.h"
4 #include "interlacemodes.h"
5 #include "vframe.h"
8 FileGIF::FileGIF(Asset *asset)
9  : FileBase(asset)
11         reset_parameters();
12         asset->video_data = 1;
13         asset->format = FILE_GIF;
16 FileGIF::~FileGIF()
18         close_file();
21 int FileGIF::reset_parameters_derived()
23         data = 0;
26 int FileGIF::open_file(int rd, int wr)
28         this->rd = rd;
29         this->wr = wr;
31 // skip header for write
32         if(wr)
33         {
34         }
35         else
36         if(rd)
37         {
38                 return read_header();
39         }
40         return 0;
43 int64_t FileGIF::get_video_length()
45         return -1;    // infinity
46 // should be determined by whether the GIF is animated
49 int64_t FileGIF::get_memory_usage()
51 // give buffer length plus padding
52         if(data)
53                 return (int64_t)asset->width * asset->height * sizeof(VPixel);
54         else
55                 return 256;
58 int FileGIF::close_file_derived()
60         if(data) delete data;
61         reset_parameters();
64 int FileGIF::read_header()
66         GIF *stream;
68         if(!(stream = GIFOpen(asset->path, "r")))
69         {
70                 eprintf("Error while opening \"%s\" for reading. \n%m\n", asset->path);
71                 return 1;
72         }
73         
74         GIFGetField(stream, GIFTAG_IMAGEWIDTH, &(asset->width));
75         GIFGetField(stream, GIFTAG_IMAGELENGTH, &(asset->height));
76         asset->interlacemode = BC_ILACE_MODE_NOTINTERLACED;
77         asset->layers = 1;
79         GIFClose(stream);
80         return 0;
84 VFrame* FileGIF::read_frame(int use_alpha, int use_float)
86         read_raw();
87         return data;
90 int FileGIF::read_raw()
92         if(!data)
93         {
94 // read the raw data
95                 GIF *stream;
96                 unsigned char *raw_data;
97                 int i;
99                 if(!(stream = GIFOpen(asset->path, "r")))
100                 {
101                         eprintf("Error while opening \"%s\" for writing. \n%m\n", asset->path);
102                         return 1;
103                 }
105                 raw_data = new unsigned char[asset->width * asset->height * 4];
106                 GIFReadRGBAImage(stream, asset->width, asset->height, (uint32*)raw_data, 0);
108                 GIFClose(stream);
110 // convert to a Bcast 2000 Frame
111                 data = new VFrame(asset->width, asset->height);
113                 for(i = 0; i < asset->height; i++)
114                 {
115                         import_row(data->rows[asset->height - i - 1], &raw_data[i * asset->width * 4]);
116                 }
118 // delete temporary buffers
119                 delete raw_data;
120         }
121         return 0;
124 int FileGIF::import_row(VPixel *output, unsigned char *row_pointer)
126         for(int i = 0, j = 0; j < asset->width; j++)
127         {
128 #if (VMAX == 65535)
129                 output[j].red =  ((VWORD)row_pointer[i++]) << 8;
130                 output[j].green =  ((VWORD)row_pointer[i++]) << 8;
131                 output[j].blue = ((VWORD)row_pointer[i++]) << 8;
132                 output[j].alpha = ((VWORD)row_pointer[i++]) << 8;
133 #else
134                 output[j].red =  (VWORD)row_pointer[i++];
135                 output[j].green =  (VWORD)row_pointer[i++];
136                 output[j].blue = (VWORD)row_pointer[i++];
137                 output[j].alpha = (VWORD)row_pointer[i++];
138 #endif
139         }