~ubuntu-branches/ubuntu/oneiric/libclaw/oneiric

« back to all changes in this revision

Viewing changes to claw/code/bitmap_reader.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Julien Jorge
  • Date: 2008-05-17 15:36:57 UTC
  • Revision ID: james.westby@ubuntu.com-20080517153657-0b1204j754ykoz48
Tags: upstream-1.5.2b
ImportĀ upstreamĀ versionĀ 1.5.2b

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
  CLAW - a C++ Library Absolutely Wonderful
 
3
 
 
4
  CLAW is a free library without any particular aim but being useful to 
 
5
  anyone.
 
6
 
 
7
  Copyright (C) 2005-2008 Julien Jorge
 
8
 
 
9
  This library is free software; you can redistribute it and/or
 
10
  modify it under the terms of the GNU Lesser General Public
 
11
  License as published by the Free Software Foundation; either
 
12
  version 2.1 of the License, or (at your option) any later version.
 
13
 
 
14
  This library is distributed in the hope that it will be useful,
 
15
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
16
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
17
  Lesser General Public License for more details.
 
18
 
 
19
  You should have received a copy of the GNU Lesser General Public
 
20
  License along with this library; if not, write to the Free Software
 
21
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
22
 
 
23
  contact: julien_jorge@yahoo.fr
 
24
*/
 
25
/**
 
26
 * \file bitmap_reader.cpp
 
27
 * \brief Implementation of the claw::graphic::bitmap::reader class.
 
28
 * \author Julien Jorge
 
29
 */
 
30
#include <claw/bitmap.hpp>
 
31
#include <algorithm>
 
32
 
 
33
namespace claw
 
34
{
 
35
  namespace graphic
 
36
  {
 
37
    /*------------------------------------------------------------------------*/
 
38
    /**
 
39
     * \brief Copy a color a certain number of times.
 
40
     * \param n Number of copies.
 
41
     * \param pattern The index of the color to copy.
 
42
     * \remark This method is for 8bpp bitmaps.
 
43
     */
 
44
    template<>
 
45
    void bitmap::reader::rle_bitmap_output_buffer<false>::fill
 
46
    ( unsigned int n, unsigned char pattern )
 
47
    {
 
48
      assert( m_x + n <= m_image.width() );
 
49
      
 
50
      std::fill(&m_image[m_y][m_x], &m_image[m_y][m_x] + n, m_palette[pattern]);
 
51
      
 
52
      m_x += n;
 
53
    } // bitmap::reader::rle_bitmap_output_buffer<false>::fill()
 
54
  } // namespace graphic
 
55
} // namespace claw
 
56
 
 
57
namespace claw
 
58
{
 
59
  namespace graphic
 
60
  {
 
61
    /*------------------------------------------------------------------------*/
 
62
    /**
 
63
     * \brief Copy a pair of colors a certain number of times.
 
64
     * \param n Number of pixels to fill.
 
65
     * \param pattern The index of the two colors to copy.
 
66
     * \remark This method is for 4bpp bitmaps.
 
67
     */
 
68
    template<>
 
69
    void bitmap::reader::rle_bitmap_output_buffer<true>::fill
 
70
    ( unsigned int n, unsigned char pattern )
 
71
    {
 
72
      assert( m_x + n <= m_image.width() );
 
73
      
 
74
      for (unsigned int i = 0; i != n / 2; ++i, m_x += 2)
 
75
        {
 
76
          m_image[m_y][m_x] = m_palette[ (pattern & 0xF0) >> 4 ];
 
77
          m_image[m_y][m_x+1] = m_palette[ pattern & 0x0F ];
 
78
        }
 
79
      
 
80
      if ( n % 2 )
 
81
        {
 
82
          m_image[m_y][m_x] = m_palette[ (pattern & 0xF0) >> 4 ];
 
83
          ++m_x;
 
84
        }
 
85
    } // bitmap::reader::rle_bitmap_output_buffer<false>::fill()
 
86
  } // namespace graphic
 
87
} // namespace claw
 
88
 
 
89
namespace claw
 
90
{
 
91
  namespace graphic
 
92
  {
 
93
    /*------------------------------------------------------------------------*/
 
94
    /**
 
95
     * \brief Copy some pixels directly.
 
96
     * \param n The number of pixels to copy.
 
97
     * \param buffer The input buffer, to copy from.
 
98
     * \remark This method is for 8bpp bitmaps.
 
99
     */
 
100
    template<>
 
101
    void bitmap::reader::rle_bitmap_output_buffer<false>::copy
 
102
    ( unsigned int n, file_input_buffer& buffer )
 
103
    {
 
104
      assert( m_x + n <= m_image.width() );
 
105
      
 
106
      // RLE bitmap data is 2-bytes aligned
 
107
      const unsigned int bytes_needed = n + n % 2;
 
108
      
 
109
      if ( buffer.remaining() < bytes_needed )
 
110
        buffer.read_more(bytes_needed);
 
111
      
 
112
      assert( buffer.remaining() >= bytes_needed );
 
113
      
 
114
      const unsigned char* p =
 
115
        reinterpret_cast<const unsigned char*>(buffer.get_buffer());
 
116
      
 
117
      std::transform( p, p + n, &m_image[m_y][m_x], m_palette );
 
118
      
 
119
      m_x += n;
 
120
 
 
121
      buffer.move(bytes_needed);
 
122
    } // bitmap::reader::rle_bitmap_output_buffer<false>::copy()
 
123
  } // namespace graphic
 
124
} // namespace claw
 
125
 
 
126
namespace claw
 
127
{
 
128
  namespace graphic
 
129
  {
 
130
    /*------------------------------------------------------------------------*/
 
131
    /**
 
132
     * \brief Copy some pixels directly.
 
133
     * \param n The number of pixels to copy.
 
134
     * \param buffer The input buffer, to copy from.
 
135
     * \remark This method is for 4bpp bitmaps.
 
136
     */
 
137
    template<>
 
138
    void bitmap::reader::rle_bitmap_output_buffer<true>::copy
 
139
    ( unsigned int n, file_input_buffer& buffer )
 
140
    {
 
141
      assert( m_x + n <= m_image.width() );
 
142
 
 
143
      // RLE bitmap data is 2-bytes aligned
 
144
      unsigned int bytes_needed = n / 2 + n % 2;
 
145
 
 
146
      if ( bytes_needed % 2 )
 
147
        ++bytes_needed;
 
148
 
 
149
      if ( buffer.remaining() < bytes_needed )
 
150
        buffer.read_more( bytes_needed );
 
151
 
 
152
      assert( buffer.remaining() >= bytes_needed );
 
153
 
 
154
      const unsigned char* p =
 
155
        reinterpret_cast<const unsigned char*>(buffer.get_buffer());
 
156
      const unsigned char* last = p + n / 2;
 
157
 
 
158
      for ( ; p != last; ++p, m_x += 2)
 
159
        {
 
160
          m_image[m_y][m_x] = m_palette[ (*p & 0xF0) >> 4 ];
 
161
          m_image[m_y][m_x+1] = m_palette[ *p & 0x0F ];
 
162
        }
 
163
 
 
164
      if ( n % 2 )
 
165
        {
 
166
          m_image[m_y][m_x] = m_palette[ (*p & 0xF0) >> 4 ];
 
167
          ++m_x;
 
168
        }
 
169
 
 
170
      buffer.move( bytes_needed );
 
171
    } // bitmap::reader::rle_bitmap_output_buffer<true>::copy()
 
172
  } // namespace graphic
 
173
} // namespace claw
 
174
 
 
175
 
 
176
 
 
177
/*----------------------------------------------------------------------------*/
 
178
/**
 
179
 * \brief Convert a bitset array to a pixel32 scanline.
 
180
 * \param dest (out) Filled scanline.
 
181
 * \param src Pixel array to convert.
 
182
 * \param palette Color palette.
 
183
 * \pre palette.size() == 2
 
184
 */
 
185
void claw::graphic::bitmap::reader::pixel1_to_pixel32::operator()
 
186
  ( scanline& dest, const char* src, const color_palette_type& palette ) const
 
187
{
 
188
  assert(palette.size() == 2);
 
189
 
 
190
  scanline::iterator it( dest.begin() );
 
191
  const unsigned int n = dest.size();
 
192
  const unsigned int byte_size = 8; // 8 bits per byte
 
193
  const unsigned int upper_bound = n / byte_size;
 
194
 
 
195
  for (unsigned int i=0; i!=upper_bound; ++i)
 
196
    for (unsigned int j=0; j!=byte_size; ++j, ++it)
 
197
      if ( src[i] & (0x80 >> j) )
 
198
        *it = palette[1];
 
199
      else
 
200
        *it = palette[0];
 
201
 
 
202
  for (unsigned int j = 0; j != (n % byte_size); ++j, ++it)
 
203
    if ( src[upper_bound] & (0x80 >> j) )
 
204
      *it = palette[1];
 
205
    else
 
206
      *it = palette[0];
 
207
} // bitmap::reader::pixel1_to_pixel32()
 
208
 
 
209
/*----------------------------------------------------------------------------*/
 
210
/**
 
211
 * \brief Convert a 4bpp array to a pixel32 scanline.
 
212
 * \param dest (out) Filled scanline.
 
213
 * \param src Pixel array to convert.
 
214
 * \param palette Color palette.
 
215
 * \pre palette.size() == 16
 
216
 */
 
217
void claw::graphic::bitmap::reader::pixel4_to_pixel32::operator()
 
218
  ( scanline& dest, const char* src, const color_palette_type& palette ) const
 
219
{
 
220
  assert(palette.size() == 16);
 
221
 
 
222
  scanline::iterator it( dest.begin() );
 
223
  const unsigned int upper_bound = dest.size() / 2;
 
224
 
 
225
  for (unsigned int i=0; i!=upper_bound; ++i, ++src)
 
226
    {
 
227
      *it = palette[ (*src & 0xF0) >> 4 ];
 
228
      ++it;
 
229
      *it = palette[ *src & 0x0F ];
 
230
      ++it;
 
231
    }
 
232
 
 
233
  if (dest.size() % 2)
 
234
    *it = palette[ (*src & 0xF0) >> 4 ];
 
235
} // bitmap::reader::pixel4_to_pixel32()
 
236
 
 
237
/*----------------------------------------------------------------------------*/
 
238
/**
 
239
 * \brief Convert a 8bpp array to a pixel32 scanline.
 
240
 * \param dest (out) Filled scanline.
 
241
 * \param src Pixel array to convert.
 
242
 * \param palette Color palette.
 
243
 * \pre palette.size() == 256
 
244
 */
 
245
void claw::graphic::bitmap::reader::pixel8_to_pixel32::operator()
 
246
  ( scanline& dest, const char* src, const color_palette_type& palette ) const
 
247
{
 
248
  assert(palette.size() == 256);
 
249
 
 
250
  const unsigned char* s = reinterpret_cast<const unsigned char*>(src);
 
251
 
 
252
  std::transform(s, s + dest.size(), dest.begin(), palette);
 
253
} // bitmap::reader::pixel8_to_pixel32()
 
254
 
 
255
/*----------------------------------------------------------------------------*/
 
256
/**
 
257
 * \brief Convert a BGR array to a pixel32 scanline.
 
258
 * \param dest (out) Filled scanline.
 
259
 * \param src Pixel array to convert.
 
260
 * \param palette (not used) Color palette.
 
261
 */
 
262
void claw::graphic::bitmap::reader::pixel24_to_pixel32::operator()
 
263
  ( scanline& dest, const char* src, const color_palette_type& palette ) const
 
264
{
 
265
  scanline::iterator it( dest.begin() );
 
266
  const unsigned int upper_bound = 3 * dest.size();
 
267
 
 
268
  for (unsigned int i=0; i!=upper_bound; i+=3)
 
269
    {
 
270
      it->components.alpha = 255;
 
271
      it->components.blue  = src[i];
 
272
      it->components.green = src[i+1];
 
273
      it->components.red   = src[i+2];
 
274
 
 
275
      ++it;
 
276
    }
 
277
} // bitmap::reader::pixel24_to_pixel32()
 
278
 
 
279
 
 
280
 
 
281
 
 
282
/*----------------------------------------------------------------------------*/
 
283
/**
 
284
 * \brief Constructor.
 
285
 * \param img The image in which the data will be stored.
 
286
 */
 
287
claw::graphic::bitmap::reader::reader( image& img )
 
288
  : m_image( img )
 
289
{
 
290
 
 
291
} // bitmap::reader::reader()
 
292
 
 
293
/*----------------------------------------------------------------------------*/
 
294
/**
 
295
 * \brief Constructor.
 
296
 * \param img The image in which the data will be stored.
 
297
 * \param f The file from which we read the data.
 
298
 * \post img contains the data from \a f.
 
299
 */
 
300
claw::graphic::bitmap::reader::reader( image& img, std::istream& f )
 
301
  : m_image( img )
 
302
{
 
303
  load(f);
 
304
} // bitmap::reader::reader()
 
305
 
 
306
/*----------------------------------------------------------------------------*/
 
307
/**
 
308
 * \brief Load the image data from a stream.
 
309
 * \param f The file from which we read the data.
 
310
 * \post The image passed to the constructor contains the data from \a f.
 
311
 */
 
312
void claw::graphic::bitmap::reader::load( std::istream& f )
 
313
{
 
314
  CLAW_PRECOND( !!f );
 
315
  std::istream::pos_type init_pos = f.tellg();
 
316
 
 
317
  try
 
318
    {
 
319
      header h;
 
320
 
 
321
      f.read( reinterpret_cast<char*>(&h), sizeof(header) );
 
322
 
 
323
      if ( (h.id[0] == 'B') && (h.id[1] == 'M')
 
324
           && (f.rdstate() == std::ios_base::goodbit) )
 
325
        {
 
326
          m_image.set_size(h.width, h.height);
 
327
      
 
328
          switch(h.bpp)
 
329
            {
 
330
            case 1 : load_1bpp(h, f); break;
 
331
            case 4 : load_4bpp(h, f); break;
 
332
            case 8 : load_8bpp(h, f); break;
 
333
              //case 16 : load_16bpp(h, f); break;
 
334
            case 24 : load_24bpp(h, f); break;
 
335
            default : 
 
336
              throw claw::bad_format
 
337
                ("bitmap::bitmap: unsupported color depth.");
 
338
            }
 
339
        }
 
340
      else
 
341
        throw claw::bad_format( "bitmap::bitmap: invalid header." );
 
342
    }
 
343
  catch(...)
 
344
    {
 
345
      f.clear();
 
346
      f.seekg( init_pos, std::ios_base::beg );
 
347
      throw;
 
348
    }
 
349
} // bitmap::reader::load()
 
350
 
 
351
/*----------------------------------------------------------------------------*/
 
352
/**
 
353
 * \brief Load the palette of the image.
 
354
 * \param h File's header, must have been read before call.
 
355
 * \param f Bitmap file.
 
356
 * \param palette The loaded palette.
 
357
 * \pre h.bpp <= 8
 
358
 */
 
359
void claw::graphic::bitmap::reader::load_palette
 
360
( const header& h, std::istream& f, color_palette_type& palette ) const
 
361
{
 
362
  assert(h.bpp <= 8);
 
363
 
 
364
  switch(h.bpp)
 
365
    {
 
366
    case 1 : assert( palette.size() == 2 ); break;
 
367
    case 4 : assert( palette.size() == 16 ); break;
 
368
    case 8 : assert( palette.size() == 256 ); break;
 
369
    }
 
370
 
 
371
  const unsigned int sizeof_color = sizeof(color_palette_type::color_type);
 
372
  const unsigned int buffer_size = sizeof_color * palette.size();
 
373
  char* buffer = new char[buffer_size];
 
374
 
 
375
  f.read(buffer, buffer_size);
 
376
 
 
377
  for (unsigned int i=0, j=0; i!=buffer_size; i+=sizeof_color, ++j)
 
378
    {
 
379
      palette[j].components.alpha = 255;
 
380
      palette[j].components.blue  = buffer[i];
 
381
      palette[j].components.green = buffer[i+1];
 
382
      palette[j].components.red   = buffer[i+2];
 
383
    }
 
384
 
 
385
  delete[] buffer;
 
386
} // bitmap::reader::load_palette()
 
387
 
 
388
/*----------------------------------------------------------------------------*/
 
389
/**
 
390
 * \brief Load a monochrome bitmap file.
 
391
 * \param h File's header, must have been read before call.
 
392
 * \param f Bitmap file.
 
393
 * \pre h.bpp == 1
 
394
 */
 
395
void
 
396
claw::graphic::bitmap::reader::load_1bpp( const header& h, std::istream& f )
 
397
{
 
398
  assert(h.bpp == 1);
 
399
  //assert(h.compression == BMP_COMPRESSION_BITFIELDS);
 
400
 
 
401
  color_palette_type palette(2);
 
402
  unsigned int buffer_size = m_image.width() / (sizeof(char) * 8);
 
403
        
 
404
  if ( m_image.width() % (sizeof(char) * 8) )
 
405
    ++buffer_size;
 
406
    
 
407
  load_palette(h, f, palette);
 
408
  f.seekg(h.data_offset);
 
409
 
 
410
  load_rgb_data(f, buffer_size, palette, pixel1_to_pixel32());
 
411
} // bitmap::reader::load_1bpp()
 
412
 
 
413
/*----------------------------------------------------------------------------*/
 
414
/**
 
415
 * \brief Loads a 4 bpp bitmap file.
 
416
 * \param h File's header, must have been read before call.
 
417
 * \param f Bitmap file.
 
418
 * \pre (h.bpp == 4)
 
419
 */
 
420
void
 
421
claw::graphic::bitmap::reader::load_4bpp( const header& h, std::istream& f )
 
422
{
 
423
  assert(h.bpp == 4);
 
424
  assert( (h.compression == BMP_COMPRESSION_RGB)
 
425
          || (h.compression == BMP_COMPRESSION_RLE4) );
 
426
 
 
427
  color_palette_type palette(16);
 
428
  load_palette(h, f, palette);
 
429
 
 
430
  if (h.compression == BMP_COMPRESSION_RLE4)
 
431
    load_4bpp_rle(h, f, palette);
 
432
  else
 
433
    load_4bpp_rgb(h, f, palette);
 
434
} // bitmap::reader::load_4bpp()
 
435
 
 
436
/*----------------------------------------------------------------------------*/
 
437
/**
 
438
 * \brief Loads a 8 bpp bitmap file.
 
439
 * \param h File's header, must have been read before call.
 
440
 * \param f Bitmap file.
 
441
 * \pre (h.bpp == 8)
 
442
 */
 
443
void
 
444
claw::graphic::bitmap::reader::load_8bpp( const header& h, std::istream& f )
 
445
{
 
446
  assert(h.bpp == 8);
 
447
  assert( (h.compression == BMP_COMPRESSION_RGB)
 
448
          || (h.compression == BMP_COMPRESSION_RLE8) );
 
449
 
 
450
  color_palette_type palette(256);
 
451
  load_palette(h, f, palette);
 
452
 
 
453
  if (h.compression == BMP_COMPRESSION_RLE8)
 
454
    load_8bpp_rle(h, f, palette);
 
455
  else
 
456
    load_8bpp_rgb(h, f, palette);
 
457
} // bitmap::reader::load_8bpp()
 
458
 
 
459
/*----------------------------------------------------------------------------*/
 
460
/**
 
461
 * \brief Loads a 24 bpp bitmap file.
 
462
 * \param h File's header, must have been read before call.
 
463
 * \param f Bitmap file.
 
464
 * \pre (h.bpp == 24)
 
465
 */
 
466
void
 
467
claw::graphic::bitmap::reader::load_24bpp( const header& h, std::istream& f )
 
468
{
 
469
  assert(h.bpp == 24);
 
470
 
 
471
  unsigned int buffer_size = m_image.width() * 3;
 
472
  color_palette_type palette(0);
 
473
        
 
474
  f.seekg(h.data_offset);
 
475
 
 
476
  load_rgb_data(f, buffer_size, palette, pixel24_to_pixel32());
 
477
} // bitmap::reader::load_24bpp()
 
478
 
 
479
/*----------------------------------------------------------------------------*/
 
480
/**
 
481
 * \brief Loads a 4 bpp RLE encoded bitmap file.
 
482
 * \param h File's header and palette, must have been read before call.
 
483
 * \param f Bitmap file.
 
484
 * \param palette The color palette to use for converting colors.
 
485
 * \pre (h.bpp == 4) && (h.compression = BMP_COMPRESSION_RLE4)
 
486
 *      && (palette.size() == 16)
 
487
 */
 
488
void claw::graphic::bitmap::reader::load_4bpp_rle
 
489
( const header& h, std::istream& f, const color_palette_type& palette )
 
490
{
 
491
  assert(h.bpp == 4);
 
492
  assert(h.compression == BMP_COMPRESSION_RLE4);
 
493
  assert(palette.size() == 16);
 
494
 
 
495
  f.seekg(h.data_offset);
 
496
 
 
497
  rle4_decoder decoder;
 
498
  rle4_decoder::output_buffer_type output_buffer( palette, m_image );
 
499
  file_input_buffer input_buffer(f);
 
500
 
 
501
  decoder.decode( input_buffer, output_buffer );
 
502
} // bitmap::reader::load_4bpp_rle()
 
503
 
 
504
/*----------------------------------------------------------------------------*/
 
505
/**
 
506
 * \brief Loads a 4 bpp RGB encoded bitmap file.
 
507
 * \param h File's header and palette, must have been read before call.
 
508
 * \param f Bitmap file.
 
509
 * \param palette The color palette to use for converting colors.
 
510
 * \pre (h.bpp == 4) && (h.compression = BMP_COMPRESSION_RGB)
 
511
 *      && (palette.size() == 16)
 
512
 */
 
513
void claw::graphic::bitmap::reader::load_4bpp_rgb
 
514
( const header& h, std::istream& f, const color_palette_type& palette )
 
515
{
 
516
  assert(h.bpp == 4);
 
517
  assert(h.compression == BMP_COMPRESSION_RGB);
 
518
  assert(palette.size() == 16);
 
519
 
 
520
  unsigned int buffer_size = m_image.width() / 2 + m_image.width() % 2;
 
521
    
 
522
  f.seekg(h.data_offset);
 
523
 
 
524
  load_rgb_data(f, buffer_size, palette, pixel4_to_pixel32());
 
525
} // bitmap::reader::load_4bpp_rgb()
 
526
 
 
527
/*----------------------------------------------------------------------------*/
 
528
/**
 
529
 * \brief Loads a 8 bpp bitmap file.
 
530
 * \param h File's header and palette, must have been read before call.
 
531
 * \param f Bitmap file.
 
532
 * \param palette The color palette to use for converting colors.
 
533
 * \pre (h.bpp == 8) && (h.compression = BMP_COMPRESSION_RLE8)
 
534
 *      && (palette.size() == 256)
 
535
 */
 
536
void claw::graphic::bitmap::reader::load_8bpp_rle
 
537
( const header& h, std::istream& f, const color_palette_type& palette )
 
538
{
 
539
  assert(h.bpp == 8);
 
540
  assert(h.compression == BMP_COMPRESSION_RLE8);
 
541
  assert(palette.size() == 256);
 
542
 
 
543
  f.seekg(h.data_offset);
 
544
 
 
545
  rle8_decoder decoder;
 
546
  rle8_decoder::output_buffer_type output_buffer( palette, m_image );
 
547
  file_input_buffer input_buffer(f);
 
548
 
 
549
  decoder.decode( input_buffer, output_buffer );
 
550
} // bitmap::reader::load_8bpp_rle()
 
551
 
 
552
/*----------------------------------------------------------------------------*/
 
553
/**
 
554
 * \brief Loads a 8 bpp RGB encoded bitmap file.
 
555
 * \param h File's header and palette, must have been read before call.
 
556
 * \param f Bitmap file.
 
557
 * \param palette The color palette to use for converting colors.
 
558
 * \pre (h.bpp == 8) && (h.compression = BMP_COMPRESSION_RGB)
 
559
 *      && (palette.size() == 256)
 
560
 */
 
561
void claw::graphic::bitmap::reader::load_8bpp_rgb
 
562
( const header& h, std::istream& f, const color_palette_type& palette )
 
563
{
 
564
  assert(h.bpp == 8);
 
565
  assert(h.compression == BMP_COMPRESSION_RGB);
 
566
  assert(palette.size() == 256);
 
567
 
 
568
  unsigned int buffer_size = m_image.width();
 
569
    
 
570
  f.seekg(h.data_offset);
 
571
 
 
572
  load_rgb_data(f, buffer_size, palette, pixel8_to_pixel32());
 
573
} // bitmap::reader::load_8bpp_rgb()