📄 bcbitmap.c
字号:
#include "bcbitmap.h"#include <stdlib.h>BC_Bitmap::BC_Bitmap(BC_Window *top_level, int w, int h, int depth){ this->top_level = top_level; this->w = w; this->h = h; this->depth = depth; data = 0; use_shm = 0;// test shared memory if (use_shm && XShmQueryExtension(top_level->display) != 1) { printf("BC_Bitmap::BC_Bitmap Your X server doesn't support shared memory.\n"); use_shm = 0; } allocate_data();}BC_Bitmap::~BC_Bitmap(){ delete_data();}BC_Bitmap::write_drawable(Drawable &pixmap, int dest_x, int dest_y, int source_x, int source_y, int w, int h){//printf("BC_Bitmap::write_drawable %d %d %d %d\n", dest_x, dest_y, w, h); if(use_shm) XShmPutImage(top_level->display, pixmap, top_level->gc, ximage, source_x, source_y, dest_x, dest_y, w, h, 0); else XPutImage(top_level->display, pixmap, top_level->gc, ximage, source_x, source_y, dest_x, dest_y, w, h);// // for(int i = 0; i < this->h; i++)// {// for(int j = 0; j < this->w * depth / 8; j++)// {// printf("%d", row_data[i][j] ? 1 : 0);// }// printf("\n");// }}// the bitmap must be wholly contained in the source during a GetImageBC_Bitmap::read_drawable(Drawable &pixmap, int source_x, int source_y){//printf("BC_Bitmap::read_drawable %x %x %d %d %d %d\n", ximage->data, pixmap, source_x, source_y, w, h); if(use_shm) XShmGetImage(top_level->display, pixmap, ximage, source_x, source_y, 0xffffffff); else XGetSubImage(top_level->display, pixmap, source_x, source_y, w, h, 0xffffffff, ZPixmap, ximage, 0, 0);}BC_Bitmap::read_frame(VFrame *frame, int x1, int y1, int x2, int y2){ float zoom_x, zoom_y; zoom_x = (float)w / (x2 - x1); zoom_y = (float)h / (y2 - y1); if(zoom_x == 1) transfer_direct(frame, x1, y1, x2, y2); else transfer_reduce(frame, x1, y1, x2, y2);}BC_Bitmap::transfer_direct(VFrame *frame, int x1, int y1, int x2, int y2){ int y_in, y_out, width; width = x2 - x1;//printf("BC_Bitmap::transfer_direct 1 width %d w %d\n", width, w); for(y_in = y1, y_out = 0; y_in < y2; y_in++, y_out++) { switch(top_level->depth) { case 8: transfer_row_direct_8(row_data[y_out], &(frame->rows[y_in][x1]), width); break; case 16: transfer_row_direct_16((unsigned short*)row_data[y_out], &(frame->rows[y_in][x1]), width); break; case 24: transfer_row_direct_24(row_data[y_out], &(frame->rows[y_in][x1]), width); break; } }//printf("BC_Bitmap::transfer_direct 2\n");}BC_Bitmap::transfer_reduce(VFrame *frame, int x1, int y1, int x2, int y2){//printf("BC_Bitmap::transfer_reduce 1\n"); int y_out, i; float width, height; width = x2 - x1; height = y2 - y1; int column_table[w]; // table of input columns for each bitmap column int row_table[h]; // table of input rows for each bitmap row float hscale = width / w; float vscale = height / h; for(i = 0; i < w; i++) { column_table[i] = (int)(hscale * i); } for(i = 0; i < h; i++) { row_table[i] = (int)(vscale * i) + y1; }//printf("BC_Bitmap::transfer_reduce 1\n");//printf("BC_Bitmap::transfer_reduce %d %d %d %d %d %d\n", w, h, x1, y1, x2, y2); for(y_out = 0; y_out < h; y_out++) { switch(top_level->depth) { case 8: transfer_row_reduce_8(row_data[y_out], &(frame->rows[row_table[y_out]][x1]), column_table); break; case 16: transfer_row_reduce_16((unsigned short*)row_data[y_out], &(frame->rows[row_table[y_out]][x1]), column_table); break; case 24: transfer_row_reduce_24(row_data[y_out], &(frame->rows[row_table[y_out]][x1]), column_table); break; } }//printf("BC_Bitmap::transfer_reduce 2\n");}BC_Bitmap::transfer_row_direct_8(unsigned char *output, VPixel *input, int width){ for(register int x = 0; x < width; x++) { transfer_pixel_8(&output, &input[x]); }}BC_Bitmap::transfer_row_reduce_8(unsigned char *output, VPixel *input, int *column_table){ for(register int x = 0; x < w; x++) { transfer_pixel_8(&output, &input[column_table[x]]); }}BC_Bitmap::transfer_row_direct_16(unsigned short *output, VPixel *input, int width){ for(register int x = 0; x < width; x++) { transfer_pixel_16(&output, &input[x]); }}BC_Bitmap::transfer_row_reduce_16(unsigned short *output, VPixel *input, int *column_table){ for(register int x = 0; x < w; x++) { transfer_pixel_16(&output, &input[column_table[x]]); }}BC_Bitmap::transfer_row_direct_24(unsigned char *output, VPixel *input, int width){ for(register int x = 0; x < width; x++) { transfer_pixel_24(&output, &input[x]); }}BC_Bitmap::transfer_row_reduce_24(unsigned char *output, VPixel *input, int *column_table){ for(register int x = 0; x < w; x++) { transfer_pixel_24(&output, &input[column_table[x]]); }}BC_Bitmap::transfer_pixel_8(unsigned char **result, VPixel *input){ if(sizeof(VWORD) == 1) { **result = (unsigned char)(input->red & 0xc0); **result += (unsigned char)((input->green & 0xe0) >> 2); *(*result)++ += (unsigned char)((input->blue & 0xe0) >> 5); } else { **result = (unsigned char)((input->red & 0xc000) >> 8); **result += (unsigned char)((input->green & 0xe000) >> 10); *(*result)++ += (unsigned char)((input->blue & 0xe000) >> 13); }}BC_Bitmap::transfer_pixel_16(unsigned short **result, VPixel *input){ if(sizeof(VWORD) == 1) { **result = (unsigned short)(input->red & 0xf8) << 8; **result += (unsigned short)(input->green & 0xfc) << 3; *(*result)++ += (unsigned short)(input->blue & 0xf8) >> 3; } else { **result = (unsigned short)(input->red & 0xf800); **result += (unsigned short)(input->green & 0xfc00) >> 5; *(*result)++ += (unsigned short)(input->blue & 0xf800) >> 11; }}BC_Bitmap::transfer_pixel_24(unsigned char **result, VPixel *input){// reversed depending on byte order of X server if(sizeof(VWORD) == 1) { *(*result)++ = (unsigned char)(input->blue); *(*result)++ = (unsigned char)(input->green); *(*result)++ = (unsigned char)(input->red); } else { *(*result)++ = (unsigned char)(input->blue >> 8); *(*result)++ = (unsigned char)(input->green >> 8); *(*result)++ = (unsigned char)(input->red >> 8); }}BC_Bitmap::rotate_90(int side){ unsigned char** new_data; int i, j, k, l, m, step = depth / 8; int row_bytes = side * step; new_data = new unsigned char*[side]; for(i = 0; i < side; i++) new_data[i] = new unsigned char[(side + 1) * step]; for(i = 0; i < side; i++) {// scan a row from row_data to a column from new_data j = (side - i) * step; for(k = 0, m = 0; k < side; k++, m += step) { for(l = 0; l < step; l++) { new_data[k][j + l] = row_data[i][m + l]; } } } for(i = 0; i < side; i++) { for(j = 0; j < row_bytes; j++) { row_data[i][j] = new_data[i][j];//printf("%d", row_data[i][j] ? 1 : 0); }//printf("\n"); } for(i = 0; i < side; i++) delete new_data[i]; delete new_data;}BC_Bitmap::allocate_data(){// try shared memory if (use_shm) { ximage = XShmCreateImage(top_level->display, top_level->vis, depth, ZPixmap, (char*)NULL, &shm_info, w, h);//printf("BC_Bitmap::allocate_data %d\n", ximage); shm_info.shmid = shmget(IPC_PRIVATE, h * ximage->bytes_per_line, IPC_CREAT | 0777); if(shm_info.shmid < 0) perror("BC_Bitmap::allocate_data shmget"); data = (unsigned char *)shmat(shm_info.shmid, NULL, 0); ximage->data = shm_info.shmaddr = (char*)data; // setting ximage->data stops BadValue shm_info.readOnly = 0; if(!XShmAttach(top_level->display, &shm_info)) { perror("BC_Bitmap::allocate_data XShmAttach"); } } else { data = (unsigned char*)malloc(w * h * depth / 8); ximage = XCreateImage(top_level->display, top_level->vis, depth, ZPixmap, 0, (char*)data, w, h, 8, 0); } row_data = new unsigned char*[h]; for(int i = 0; i < h; i++) { row_data[i] = &data[i * ximage->bytes_per_line]; }}BC_Bitmap::delete_data(){ if(data) { if(use_shm) { XShmDetach(top_level->display, &shm_info); XDestroyImage(ximage); shmdt(shm_info.shmaddr); shmctl(shm_info.shmid, IPC_RMID, 0); } else { XDestroyImage(ximage); }// data is automatically freed by XDestroyImage data = 0; delete row_data; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -