r701: Jean-Luc Coulon has gettextized [tm] 2 more strings in the time average effect.
[cinelerra_cv.git] / guicast / bcbitmap.C
blobcec822c8c7ad9350851d64c4779f040bb818a8fc
1 #include "bcbitmap.h"
2 #include "bcipc.h"
3 #include "bcresources.h"
4 #include "bcsignals.h"
5 #include "bcwindow.h"
6 #include "colormodels.h"
7 #include "vframe.h"
9 #include <string.h>
10 #include <X11/extensions/Xvlib.h>
13 BC_Bitmap::BC_Bitmap(BC_WindowBase *parent_window, unsigned char *png_data)
15 // Decompress data into a temporary vframe
16         VFrame frame;
18         frame.read_png(png_data);
20 // Initialize the bitmap
21         initialize(parent_window, 
22                 frame.get_w(), 
23                 frame.get_h(), 
24                 parent_window->get_color_model(), 
25                 0);
27 // Copy the vframe to the bitmap
28         read_frame(&frame, 0, 0, w, h);
31 BC_Bitmap::BC_Bitmap(BC_WindowBase *parent_window, VFrame *frame)
33 // Initialize the bitmap
34         initialize(parent_window, 
35                 frame->get_w(), 
36                 frame->get_h(), 
37                 parent_window->get_color_model(), 
38                 0);
40 // Copy the vframe to the bitmap
41         read_frame(frame, 0, 0, w, h);
44 BC_Bitmap::BC_Bitmap(BC_WindowBase *parent_window, 
45         int w, 
46         int h, 
47         int color_model, 
48         int use_shm)
50         initialize(parent_window, 
51                 w, 
52                 h, 
53                 color_model, 
54                 use_shm ? parent_window->get_resources()->use_shm : 0);
57 BC_Bitmap::~BC_Bitmap()
59         delete_data();
62 int BC_Bitmap::initialize(BC_WindowBase *parent_window, 
63         int w, 
64         int h, 
65         int color_model, 
66         int use_shm)
68         this->parent_window = parent_window;
69         this->top_level = parent_window->top_level;
70         this->w = w;
71         this->h = h;
72         this->color_model = color_model;
73         this->use_shm = use_shm ? parent_window->get_resources()->use_shm : 0;
74         this->bg_color = parent_window->bg_color;
75         ximage[0] = 0;
76         xv_image[0] = 0;
77         data[0] = 0;
78         last_pixmap_used = 0;
79         last_pixmap = 0;
80         current_ringbuffer = 0;
81 // Set ring buffers based on total memory used.
82 // The program icon must use multiple buffers but larger bitmaps may not fit
83 // in memory.
84         int pixelsize = cmodel_calculate_pixelsize(color_model);
85         int buffer_size = w * h * pixelsize;
87         if(buffer_size < 0x40000)
88                 ring_buffers = 4;
89         else
90                 ring_buffers = 1;
92         allocate_data();
93         return 0;
96 int BC_Bitmap::match_params(int w, int h, int color_model, int use_shm)
98         if(this->w /* != */ < w ||
99                 this->h /* != */ < h ||
100                 this->color_model != color_model ||
101                 this->use_shm != use_shm)
102         {
103                 delete_data();
104                 initialize(parent_window, w, h, color_model, use_shm);
105         }
107         return 0;
110 int BC_Bitmap::params_match(int w, int h, int color_model, int use_shm)
112         int result = 0;
113         if(this->w == w &&
114                 this->h == h &&
115                 this->color_model == color_model)
116         {
117                 if(use_shm == this->use_shm || use_shm == BC_INFINITY)
118                         result = 1;
119         }
121         return result;
125 int BC_Bitmap::allocate_data()
127         int want_row_pointers = 1;
129 // Shared memory available
130     if(use_shm)
131         {
132                 switch(color_model)
133                 {
134 // Planar YUV.  Must use BC_WindowBase::accel_available before calling this.
135                         case BC_YUV420P:
136                         case BC_YUV422P:
137 // Packed YUV
138                         case BC_YUV422:
139                                 ring_buffers = BITMAP_RING;
140                                 xv_portid = top_level->xvideo_port_id;
141 // Create the X Image
142                                 xv_image[0] = XvShmCreateImage(top_level->display, 
143                                                         xv_portid, 
144                                                         cmodel_bc_to_x(color_model),
145                                                         0, 
146                                                         w,
147                                                         h,
148                                                         &shm_info);
149 // Create the shared memory
150                                 shm_info.shmid = shmget(IPC_PRIVATE, 
151                                         xv_image[0]->data_size * ring_buffers + 4, 
152                                         IPC_CREAT | 0777);
153                                 if(shm_info.shmid < 0) perror("BC_Bitmap::allocate_data shmget");
154                                 data[0] = (unsigned char *)shmat(shm_info.shmid, NULL, 0);
155 // setting ximage->data stops BadValue
156                                 xv_image[0]->data = shm_info.shmaddr = (char*)data[0];
157                                 shm_info.readOnly = 0;
159 // Get the real parameters
160                                 w = xv_image[0]->width;
161                                 h = xv_image[0]->height;
163 // Create remaining X Images
164                                 for(int i = 1; i < ring_buffers; i++)
165                                 {
166                                         data[i] = data[0] + xv_image[0]->data_size * i;
167                                         xv_image[i] = XvShmCreateImage(top_level->display, 
168                                                                 xv_portid, 
169                                                                 cmodel_bc_to_x(color_model),
170                                                                 (char*)data[i], 
171                                                                 w,
172                                                                 h,
173                                                                 &shm_info);
174                                         xv_image[i]->data = (char*)data[i];
175                                 }
177                                 if(color_model == BC_YUV422)
178                                 {
179                                         bytes_per_line = w * 2;
180                                         bits_per_pixel = 2;
181                                         want_row_pointers = 1;
182                                 }
183                                 else
184                                 {
185                                         bytes_per_line = 0;
186                                         bits_per_pixel = 0;
187                                         want_row_pointers = 0;
188                                 }
189                                 break;
191                         default:
192 // RGB
193                                 ring_buffers = BITMAP_RING;
194 // Create first X Image
195                         ximage[0] = XShmCreateImage(top_level->display, 
196                                         top_level->vis, 
197                                         get_default_depth(), 
198                                         get_default_depth() == 1 ? XYBitmap : ZPixmap, 
199                                         (char*)NULL, 
200                                         &shm_info, 
201                                         w, 
202                                         h);
204 // Create shared memory
205                                 shm_info.shmid = shmget(IPC_PRIVATE, 
206                                         h * ximage[0]->bytes_per_line * ring_buffers + 4, 
207                                         IPC_CREAT | 0777);
208                                 if(shm_info.shmid < 0) 
209                                         perror("BC_Bitmap::allocate_data shmget");
210                                 data[0] = (unsigned char *)shmat(shm_info.shmid, NULL, 0);
211                                 ximage[0]->data = shm_info.shmaddr = (char*)data[0];  // setting ximage->data stops BadValue
212                                 shm_info.readOnly = 0;
214 // Get the real parameters
215                                 bits_per_pixel = ximage[0]->bits_per_pixel;
216                                 bytes_per_line = ximage[0]->bytes_per_line;
218 // Create remaining X Images
219                                 for(int i = 1; i < ring_buffers; i++)
220                                 {
221                                         data[i] = data[0] + h * ximage[0]->bytes_per_line * i;
222                                         ximage[i] = XShmCreateImage(top_level->display, 
223                                                                                         top_level->vis, 
224                                                                                         get_default_depth(), 
225                                                                                         get_default_depth() == 1 ? XYBitmap : ZPixmap, 
226                                                                                         (char*)data[i], 
227                                                                                         &shm_info, 
228                                                                                         w, 
229                                                                                         h);
230                                         ximage[i]->data = (char*)data[i];
231 //printf("BC_Bitmap::allocate_data %p\n", ximage[i]);
232                                 }
233                                 break;
234                 }
236                 if(!XShmAttach(top_level->display, &shm_info))
237                 {
238                         perror("BC_Bitmap::allocate_data XShmAttach");
239                 }
241 // This causes it to automatically delete when the program exits.
242                 shmctl(shm_info.shmid, IPC_RMID, 0);
243         }
244         else
245 // Use unshared memory.
246         {
247                 ring_buffers = 1;
248 // need to use bytes_per_line for some X servers
249                 data[0] = 0;
251 // Use RGB frame
252 //printf("BCBitmap::allocate_data 1\n");
253                 ximage[0] = XCreateImage(top_level->display, 
254                                         top_level->vis, 
255                                         get_default_depth(), 
256                                         get_default_depth() == 1 ? XYBitmap : ZPixmap, 
257                                         0, 
258                                         (char*)data[0], 
259                                         w, 
260                                         h, 
261                                         8, 
262                                         0);
263 //printf("BCBitmap::allocate_data 1 %d\n", h * ximage[0]->bytes_per_line + 4);
265                 data[0] = (unsigned char*)malloc(h * ximage[0]->bytes_per_line + 4);
266 //printf("BCBitmap::allocate_data 2\n");
268                 XDestroyImage(ximage[0]);
269 //printf("BCBitmap::allocate_data 1\n");
271                 ximage[0] = XCreateImage(top_level->display, 
272                                         top_level->vis, 
273                                         get_default_depth(), 
274                                         get_default_depth() == 1 ? XYBitmap : ZPixmap, 
275                                         0, 
276                                         (char*)data[0], 
277                                         w, 
278                                         h, 
279                                         8, 
280                                         0);
281 //printf("BCBitmap::allocate_data 1\n");
282 // This differs from the depth parameter of the top_level.
283                 bits_per_pixel = ximage[0]->bits_per_pixel;
284                 bytes_per_line = ximage[0]->bytes_per_line;
285 //printf("BCBitmap::allocate_data 2\n");
286         }
288 // Create row pointers
289         if(want_row_pointers)
290         {
291 //printf("BC_Bitmap::allocate 1 %d %d %d %d\n", w, h, get_default_depth(), bytes_per_line);
292                 for(int j = 0; j < ring_buffers; j++)
293                 {
294                         row_data[j] = new unsigned char*[h];
295                         for(int i = 0; i < h; i++)
296                         {
297                                 row_data[j][i] = &data[j][i * bytes_per_line];
298                         }
299                 }
300         }
301         return 0;
304 int BC_Bitmap::delete_data()
306         if(data[0])
307         {
308                 if(use_shm)
309                 {
310                         switch(color_model)
311                         {
312                                 case BC_YUV420P:
313                                 case BC_YUV422P:
314                                 case BC_YUV422:
315 //printf("BC_Bitmap::delete_data 1\n");
316                                         if(last_pixmap_used) XvStopVideo(top_level->display, xv_portid, last_pixmap);
317                                         for(int i = 0; i < ring_buffers; i++)
318                                         {
319                                                 XFree(xv_image[i]);
320                                         }
321                                         XShmDetach(top_level->display, &shm_info);
322                                         XvUngrabPort(top_level->display, xv_portid, CurrentTime);
324                                         shmdt(shm_info.shmaddr);
325                                         shmctl(shm_info.shmid, IPC_RMID, 0);
326                                         break;
328                                 default:
329                                         for(int i = 0; i < ring_buffers; i++)
330                                         {
331                                                 XDestroyImage(ximage[i]);
332                                                 delete [] row_data[i];
333                                         }
334                                         XShmDetach(top_level->display, &shm_info);
336                                         shmdt(shm_info.shmaddr);
337                                         shmctl(shm_info.shmid, IPC_RMID, 0);
338                                         break;
339                         }
340                 }
341                 else
342                 {
343                         XDestroyImage(ximage[0]);
344                         delete [] row_data[0];
345                 }
347 // data is automatically freed by XDestroyImage
348                 data[0] = 0;
349                 last_pixmap_used = 0;
350         }
351         return 0;
354 int BC_Bitmap::get_default_depth()
356         if(color_model == BC_TRANSPARENCY)
357                 return 1;
358         else
359                 return top_level->default_depth;
363 int BC_Bitmap::set_bg_color(int color)
365         this->bg_color = color;
366         return 0;
369 int BC_Bitmap::invert()
371         for(int j = 0; j < ring_buffers; j++)
372                 for(int k = 0; k < h; k++)
373                         for(int i = 0; i < bytes_per_line; i++)
374                         {
375                                 row_data[j][k][i] ^= 0xff;
376                         }
377         return 0;
380 int BC_Bitmap::write_drawable(Drawable &pixmap, 
381                                                         GC &gc,
382                                                         int dest_x, 
383                                                         int dest_y, 
384                                                         int source_x, 
385                                                         int source_y, 
386                                                         int dest_w, 
387                                                         int dest_h,
388                                                         int dont_wait)
390         return write_drawable(pixmap, 
391                 gc,
392                 source_x, 
393                 source_y, 
394                 get_w() - source_x,
395                 get_h() - source_y,
396                 dest_x, 
397                 dest_y, 
398                 dest_w, 
399                 dest_h, 
400                 dont_wait);
403 void BC_Bitmap::rewind_ring()
405         current_ringbuffer--;
406         if(current_ringbuffer < 0) current_ringbuffer = ring_buffers - 1;
409 int BC_Bitmap::write_drawable(Drawable &pixmap, 
410                 GC &gc,
411                 int source_x, 
412                 int source_y, 
413                 int source_w,
414                 int source_h,
415                 int dest_x, 
416                 int dest_y, 
417                 int dest_w, 
418                 int dest_h, 
419                 int dont_wait)
421 //printf("BC_Bitmap::write_drawable 1 %p %d\n", this, current_ringbuffer);fflush(stdout);
422     if(use_shm)
423         {
424                 if(dont_wait) XSync(top_level->display, False);
426                 if(hardware_scaling())
427                 {
428 // printf("BC_Bitmap::write_drawable %d %d %d %d -> %d %d %d %d\n", source_x, 
429 //                              source_y, 
430 //                              source_w, 
431 //                              source_h, 
432 //                              dest_x, 
433 //                              dest_y, 
434 //                              dest_w, 
435 //                              dest_h);
436 //for(int i = 0; i < 1000; i++) xv_image[current_ringbuffer]->data[i] = 255;
437 //printf("BC_Bitmap::write_drawable 2 %d %d %p %p\n", xv_portid, 
438 //      pixmap, 
439 //      gc,
440 //      xv_image[current_ringbuffer]);
441                         XvShmPutImage(top_level->display, 
442                                 xv_portid, 
443                                 pixmap, 
444                                 gc,
445                                 xv_image[current_ringbuffer], 
446                                 source_x, 
447                                 source_y, 
448                                 source_w, 
449                                 source_h, 
450                                 dest_x, 
451                                 dest_y, 
452                                 dest_w, 
453                                 dest_h, 
454                                 False);
455 // Need to pass these to the XvStopVideo
456                         last_pixmap = pixmap;
457                         last_pixmap_used = 1;
458                 }
459                 else
460                 {
461 // printf("BC_Bitmap::write_drawable %d %d %d %d -> %d %d %d %d\n", source_x, 
462 //                              source_y, 
463 //                              source_w, 
464 //                              source_h, 
465 //                              dest_x, 
466 //                              dest_y, 
467 //                              dest_w, 
468 //                              dest_h);
469                 XShmPutImage(top_level->display, 
470                                 pixmap, 
471                                 gc, 
472                                 ximage[current_ringbuffer], 
473                                 source_x, 
474                                 source_y, 
475                                 dest_x, 
476                                 dest_y, 
477                                 dest_w, 
478                                 dest_h, 
479                                 False);
480                 }
482 // Force the X server into processing all requests.
483 // This allows the shared memory to be written to again.
484                 if(!dont_wait) XSync(top_level->display, False);
485 //TRACE("BC_Bitmap::write_drawable 5");
486         }
487     else
488         {
489         XPutImage(top_level->display, 
490                         pixmap, 
491                         gc, 
492                         ximage[current_ringbuffer], 
493                         source_x, 
494                         source_y, 
495                         dest_x, 
496                         dest_y, 
497                         dest_w, 
498                         dest_h);
499         }
501 //printf("BC_Bitmap %d\n", current_ringbuffer);
502         current_ringbuffer++;
503         if(current_ringbuffer >= ring_buffers) current_ringbuffer = 0;
504 //printf("BC_Bitmap::write_drawable 2\n");fflush(stdout);
505         return 0;
511 // the bitmap must be wholly contained in the source during a GetImage
512 int BC_Bitmap::read_drawable(Drawable &pixmap, int source_x, int source_y)
514         if(use_shm)
515                 XShmGetImage(top_level->display, pixmap, ximage[current_ringbuffer], source_x, source_y, 0xffffffff);
516         else
517                 XGetSubImage(top_level->display, pixmap, source_x, source_y, w, h, 0xffffffff, ZPixmap, ximage[current_ringbuffer], 0, 0);
518         return 0;
521 // ============================ Decoding VFrames
523 int BC_Bitmap::read_frame(VFrame *frame, 
524         int x1, 
525         int y1, 
526         int x2, 
527         int y2)
529         return read_frame(frame, 
530                 0, 0, frame->get_w(), frame->get_h(),
531                 x1, y1, x2 - x1, y2 - y1);
535 int BC_Bitmap::read_frame(VFrame *frame, 
536         int in_x, 
537         int in_y, 
538         int in_w, 
539         int in_h,
540         int out_x, 
541         int out_y, 
542         int out_w, 
543         int out_h)
545         switch(color_model)
546         {
547 // Hardware accelerated bitmap
548                 case BC_YUV420P:
549                         if(frame->get_color_model() == color_model)
550                         {
551                                 memcpy(get_y_plane(), frame->get_y(), w * h);
552                                 memcpy(get_u_plane(), frame->get_u(), w * h / 4);
553                                 memcpy(get_v_plane(), frame->get_v(), w * h / 4);
554                                 break;
555                         }
557                 case BC_YUV422P:
558                         if(frame->get_color_model() == color_model)
559                         {
560                                 memcpy(get_y_plane(), frame->get_y(), w * h);
561                                 memcpy(get_u_plane(), frame->get_u(), w * h / 2);
562                                 memcpy(get_v_plane(), frame->get_v(), w * h / 2);
563                                 break;
564                         }
566                 case BC_YUV422:
567                         if(frame->get_color_model() == color_model)
568                         {
569                                 memcpy(get_data(), frame->get_data(), w * h + w * h);
570                                 break;
571                         }
573 // Software only
574                 default:
575 // printf("BC_Bitmap::read_frame %d -> %d %d %d %d %d -> %d %d %d %d\n",
576 //                              frame->get_color_model(), 
577 //                              color_model,
578 //                              in_x, 
579 //                              in_y, 
580 //                              in_w, 
581 //                              in_h,
582 //                              out_x, 
583 //                              out_y, 
584 //                              out_w, 
585 //                              out_h);
586 // printf("BC_Bitmap::read_frame 1 %d %p\n", bits_per_pixel, frame->get_rows());
587                         cmodel_transfer(row_data[current_ringbuffer], 
588                                 frame->get_rows(),
589                                 get_y_plane(),
590                                 get_u_plane(),
591                                 get_v_plane(),
592                                 frame->get_y(),
593                                 frame->get_u(),
594                                 frame->get_v(),
595                                 in_x, 
596                                 in_y, 
597                                 in_w, 
598                                 in_h,
599                                 out_x, 
600                                 out_y, 
601                                 out_w, 
602                                 out_h,
603                                 frame->get_color_model(), 
604                                 color_model,
605                                 bg_color,
606                                 frame->get_w(),
607                                 w);
608 // color model transfer_*_to_TRANSPARENCY don't care about endianness
609 // so buffer bitswaped here if needed.
610                                 if ((color_model == BC_TRANSPARENCY) && (!top_level->server_byte_order))
611                                         transparency_bitswap();
614 // printf("BC_Bitmap::read_frame 2\n");
615                         break;
616         }
619         return 0;
622 long BC_Bitmap::get_shm_id()
624         return shm_info.shmid;
627 long BC_Bitmap::get_shm_size()
629         if(xv_image[0])
630                 return xv_image[0]->data_size * ring_buffers;
631         else
632                 return h * ximage[0]->bytes_per_line;
635 long BC_Bitmap::get_shm_offset()
637         if(xv_image[0])
638                 return xv_image[0]->data_size * current_ringbuffer;
639         else
640         if(ximage[0])
641                 return h * ximage[0]->bytes_per_line * current_ringbuffer;
642         else
643                 return 0;
646 long BC_Bitmap::get_y_shm_offset()
648         if(xv_image[0])
649                 return get_shm_offset() + xv_image[current_ringbuffer]->offsets[0];
650         else
651                 return 0;
654 long BC_Bitmap::get_u_shm_offset()
656         if(xv_image[0])
657                 return get_shm_offset() + xv_image[current_ringbuffer]->offsets[2];
658         else
659                 return 0;
662 long BC_Bitmap::get_v_shm_offset()
664         if(xv_image[0])
665                 return get_shm_offset() + xv_image[current_ringbuffer]->offsets[1];
666         else
667                 return 0;
670 long BC_Bitmap::get_y_offset()
672         if(xv_image[0])
673                 return xv_image[current_ringbuffer]->offsets[0];
674         else
675                 return 0;
678 long BC_Bitmap::get_u_offset()
680         if(xv_image[0])
681                 return xv_image[current_ringbuffer]->offsets[2];
682         else
683                 return 0;
686 long BC_Bitmap::get_v_offset()
688         if(xv_image[0])
689                 return xv_image[current_ringbuffer]->offsets[1];
690         else
691                 return 0;
695 unsigned char** BC_Bitmap::get_row_pointers()
697         return row_data[current_ringbuffer];
700 int BC_Bitmap::get_bytes_per_line()
702         return bytes_per_line;
704 unsigned char* BC_Bitmap::get_data()
706 //printf("BC_Bitmap::get_data %d %p\n",current_ringbuffer , data[current_ringbuffer]);
707         return data[current_ringbuffer];
710 unsigned char* BC_Bitmap::get_y_plane()
712         if(color_model == BC_YUV420P ||
713                 color_model == BC_YUV422P)
714                 return data[current_ringbuffer] + xv_image[current_ringbuffer]->offsets[0];
715         else
716                 return 0;
719 unsigned char* BC_Bitmap::get_v_plane()
721         if(color_model == BC_YUV420P ||
722                 color_model == BC_YUV422P)
723                 return data[current_ringbuffer] + xv_image[current_ringbuffer]->offsets[1];
724         else
725                 return 0;
728 unsigned char* BC_Bitmap::get_u_plane()
730         if(color_model == BC_YUV420P ||
731                 color_model == BC_YUV422P)
732                 return data[current_ringbuffer] + xv_image[current_ringbuffer]->offsets[2];
733         else
734                 return 0;
737 void BC_Bitmap::rewind_ringbuffer()
739         current_ringbuffer--;
740         if(current_ringbuffer < 0) current_ringbuffer = ring_buffers - 1;
743 int BC_Bitmap::hardware_scaling()
745         return (get_color_model() == BC_YUV420P || 
746                 get_color_model() == BC_YUV422P || 
747                 get_color_model() == BC_YUV422);
750 int BC_Bitmap::get_w() { return w; }
752 int BC_Bitmap::get_h() { return h; }
754 char BC_Bitmap::byte_bitswap(char src) {
755         int i;
756         char dst;
758         dst = 0;
759         if (src & 1) dst |= ((unsigned char)1 << 7);
760         src = src >> 1;
761         if (src & 1) dst |= ((unsigned char)1 << 6);
762         src = src >> 1;
763         if (src & 1) dst |= ((unsigned char)1 << 5);
764         src = src >> 1;
765         if (src & 1) dst |= ((unsigned char)1 << 4);
766         src = src >> 1;
767         if (src & 1) dst |= ((unsigned char)1 << 3);
768         src = src >> 1;
769         if (src & 1) dst |= ((unsigned char)1 << 2);
770         src = src >> 1;
771         if (src & 1) dst |= ((unsigned char)1 << 1);
772         src = src >> 1;
773         if (src & 1) dst |= ((unsigned char)1 << 0);
775         return(dst);
778 void BC_Bitmap::transparency_bitswap() {
779         unsigned char *buf;
780         int i, width, height;
781         int len;
783         buf = *row_data[current_ringbuffer];
785         width = w;
786         height = h;
787         if (width % 8)
788                 width = width + 8 - (width % 8);
789         len = width * height / 8;
791         for(i=0 ; i+8<=len ; i+=8){
792                 buf[i+0] = byte_bitswap(buf[i+0]);
793                 buf[i+1] = byte_bitswap(buf[i+1]);
794                 buf[i+2] = byte_bitswap(buf[i+2]);
795                 buf[i+3] = byte_bitswap(buf[i+3]);
796                 buf[i+4] = byte_bitswap(buf[i+4]);
797                 buf[i+5] = byte_bitswap(buf[i+5]);
798                 buf[i+6] = byte_bitswap(buf[i+6]);
799                 buf[i+7] = byte_bitswap(buf[i+7]);
800         }
801         for( ; i<len ; i++){
802                 buf[i+0] = byte_bitswap(buf[i+0]);
803         }
806 int BC_Bitmap::get_color_model() { return color_model; }