6 //#include "bccounter.h"
9 #include "colormodels.h"
15 static void png_read_function(png_structp png_ptr,
19 VFrame *frame = (VFrame*)png_get_io_ptr(png_ptr);
20 if(frame->image_size - frame->image_offset < length)
21 length = frame->image_size - frame->image_offset;
23 memcpy(data, &frame->image[frame->image_offset], length);
24 frame->image_offset += length;
34 //static BCCounter counter;
37 VFrame::VFrame(unsigned char *png_data)
39 //printf("VFrame::VFrame 1\n");
41 //printf("VFrame::VFrame 1\n");
43 //printf("VFrame::VFrame 2\n");
46 VFrame::VFrame(VFrame &frame)
49 allocate_data(0, 0, 0, 0, frame.w, frame.h, frame.color_model, frame.bytes_per_line);
50 memcpy(data, frame.data, bytes_per_line * h);
54 VFrame::VFrame(unsigned char *data,
61 allocate_data(data, 0, 0, 0, w, h, color_model, bytes_per_line);
65 VFrame::VFrame(unsigned char *data,
89 this->color_model = BC_COMPRESSED;
109 int VFrame::equivalent(VFrame *src)
111 return (src->get_color_model() == get_color_model() &&
112 src->get_w() == get_w() &&
113 src->get_h() == get_h() &&
114 src->bytes_per_line == bytes_per_line);
117 long VFrame::set_shm_offset(long offset)
123 long VFrame::get_shm_offset()
128 int VFrame::params_match(int w, int h, int color_model)
130 return (this->w == w &&
132 this->color_model == color_model);
136 int VFrame::reset_parameters()
145 compressed_allocated = 0;
146 compressed_size = 0; // Size of current image
153 sequence_number = -1;
157 int VFrame::clear_objects()
160 //printf("VFrame::clear_objects 1 %p %d\n", this, shared);
163 int size = calculate_data_size(this->w, this->h, this->bytes_per_line, this->color_model);
164 if(size > 2560 * 1920)
166 if(data) delete [] data;
170 // Delete row pointers
185 int VFrame::get_field2_offset()
187 return field2_offset;
190 int VFrame::set_field2_offset(int value)
192 this->field2_offset = value;
196 int VFrame::calculate_bytes_per_pixel(int color_model)
198 return cmodel_calculate_pixelsize(color_model);
201 long VFrame::get_bytes_per_line()
203 return bytes_per_line;
206 long VFrame::get_data_size()
208 return calculate_data_size(w, h, bytes_per_line, color_model) - 4;
209 // return h * bytes_per_line;
212 long VFrame::calculate_data_size(int w, int h, int bytes_per_line, int color_model)
214 return cmodel_calculate_datasize(w, h, bytes_per_line, color_model);
218 void VFrame::create_row_pointers()
227 this->u_offset = w * h;
228 this->v_offset = w * h + w * h / 4;
230 y = this->data + this->y_offset;
231 u = this->data + this->u_offset;
232 v = this->data + this->v_offset;
239 this->u_offset = w * h;
240 this->v_offset = w * h + w * h / 2;
242 y = this->data + this->y_offset;
243 u = this->data + this->u_offset;
244 v = this->data + this->v_offset;
248 rows = new unsigned char*[h];
249 for(int i = 0; i < h; i++)
251 rows[i] = &this->data[i * this->bytes_per_line];
257 int VFrame::allocate_data(unsigned char *data,
268 this->color_model = color_model;
269 this->bytes_per_pixel = calculate_bytes_per_pixel(color_model);
270 this->y_offset = this->u_offset = this->v_offset = 0;
272 if(bytes_per_line >= 0)
274 this->bytes_per_line = bytes_per_line;
277 this->bytes_per_line = this->bytes_per_pixel * w;
279 // Allocate data + padding for MMX
284 this->y_offset = y_offset;
285 this->u_offset = u_offset;
286 this->v_offset = v_offset;
291 int size = calculate_data_size(this->w,
293 this->bytes_per_line,
295 this->data = new unsigned char[size];
297 if(size > 2560 * 1920)
298 BUFFER(size, this->data, "VFrame::allocate_data");
301 printf("VFrame::allocate_data %dx%d: memory exhausted.\n", this->w, this->h);
303 //printf("VFrame::allocate_data %p %d %d\n", this, this->w, this->h);
304 //if(size > 1000000) printf("VFrame::allocate_data %d\n", size);
307 // Create row pointers
308 create_row_pointers();
312 void VFrame::set_memory(unsigned char *data,
319 this->y_offset = y_offset;
320 this->u_offset = u_offset;
321 this->v_offset = v_offset;
322 y = this->data + this->y_offset;
323 u = this->data + this->u_offset;
324 v = this->data + this->v_offset;
325 create_row_pointers();
328 void VFrame::set_compressed_memory(unsigned char *data,
335 this->compressed_allocated = data_allocated;
336 this->compressed_size = data_size;
340 // Reallocate uncompressed buffer with or without alpha
341 int VFrame::reallocate(unsigned char *data,
363 int VFrame::allocate_compressed_data(long bytes)
365 if(bytes < 1) return 1;
367 // Want to preserve original contents
368 if(data && compressed_allocated < bytes)
370 unsigned char *new_data = new unsigned char[bytes];
371 bcopy(data, new_data, compressed_allocated);
374 compressed_allocated = bytes;
379 data = new unsigned char[bytes];
380 compressed_allocated = bytes;
387 int VFrame::read_png(unsigned char *data)
389 png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
390 png_infop info_ptr = png_create_info_struct(png_ptr);
395 image_size = (((unsigned long)data[0]) << 24) |
396 (((unsigned long)data[1]) << 16) |
397 (((unsigned long)data[2]) << 8) |
398 (unsigned char)data[3];
399 png_set_read_fn(png_ptr, this, PngReadFunction::png_read_function);
400 png_read_info(png_ptr, info_ptr);
402 w = png_get_image_width(png_ptr, info_ptr);
403 h = png_get_image_height(png_ptr, info_ptr);
405 switch(png_get_color_type(png_ptr, info_ptr))
407 case PNG_COLOR_TYPE_RGB:
408 new_color_model = BC_RGB888;
411 case PNG_COLOR_TYPE_RGB_ALPHA:
413 new_color_model = BC_RGBA8888;
426 png_read_image(png_ptr, get_rows());
427 png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
431 unsigned char* VFrame::get_data()
436 long VFrame::get_compressed_allocated()
438 return compressed_allocated;
441 long VFrame::get_compressed_size()
443 return compressed_size;
446 long VFrame::set_compressed_size(long size)
448 compressed_size = size;
452 int VFrame::get_color_model()
458 int VFrame::equals(VFrame *frame)
460 if(frame->data == data)
466 #define ZERO_YUV(components, type, max) \
468 for(int i = 0; i < h; i++) \
470 type *row = (type*)get_rows()[i]; \
471 for(int j = 0; j < w; j++) \
473 row[j * components] = 0; \
474 row[j * components + 1] = (max + 1) / 2; \
475 row[j * components + 2] = (max + 1) / 2; \
476 if(components == 4) row[j * components + 3] = 0; \
481 int VFrame::clear_frame()
489 bzero(data, h * w * 2);
493 ZERO_YUV(3, unsigned char, 0xff);
497 ZERO_YUV(4, unsigned char, 0xff);
501 ZERO_YUV(3, uint16_t, 0xffff);
504 case BC_YUVA16161616:
505 ZERO_YUV(4, uint16_t, 0xffff);
509 bzero(data, h * bytes_per_line);
515 void VFrame::rotate90()
517 // Allocate new frame
518 int new_w = h, new_h = w, new_bytes_per_line = bytes_per_pixel * new_w;
519 unsigned char *new_data = new unsigned char[calculate_data_size(new_w, new_h, new_bytes_per_line, color_model)];
520 unsigned char **new_rows = new unsigned char*[new_h];
521 for(int i = 0; i < new_h; i++)
522 new_rows[i] = &new_data[new_bytes_per_line * i];
525 for(int in_y = 0, out_x = new_w - 1; in_y < h; in_y++, out_x--)
527 for(int in_x = 0, out_y = 0; in_x < w; in_x++, out_y++)
529 for(int k = 0; k < bytes_per_pixel; k++)
531 new_rows[out_y][out_x * bytes_per_pixel + k] =
532 rows[in_y][in_x * bytes_per_pixel + k];
541 bytes_per_line = new_bytes_per_line;
546 void VFrame::rotate270()
548 // Allocate new frame
549 int new_w = h, new_h = w, new_bytes_per_line = bytes_per_pixel * new_w;
550 unsigned char *new_data = new unsigned char[calculate_data_size(new_w, new_h, new_bytes_per_line, color_model)];
551 unsigned char **new_rows = new unsigned char*[new_h];
552 for(int i = 0; i < new_h; i++)
553 new_rows[i] = &new_data[new_bytes_per_line * i];
556 for(int in_y = 0, out_x = 0; in_y < h; in_y++, out_x++)
558 for(int in_x = 0, out_y = new_h - 1; in_x < w; in_x++, out_y--)
560 for(int k = 0; k < bytes_per_pixel; k++)
562 new_rows[out_y][out_x * bytes_per_pixel + k] =
563 rows[in_y][in_x * bytes_per_pixel + k];
572 bytes_per_line = new_bytes_per_line;
577 void VFrame::flip_vert()
579 for(int i = 0, j = h - 1; i < j; i++, j--)
581 for(int k = 0; k < bytes_per_line; k++)
583 unsigned char temp = rows[j][k];
584 rows[j][k] = rows[i][k];
592 int VFrame::copy_from(VFrame *frame)
594 int w = MIN(this->w, frame->get_w());
595 int h = MIN(this->h, frame->get_h());
598 switch(frame->color_model)
601 allocate_compressed_data(frame->compressed_size);
602 memcpy(data, frame->data, frame->compressed_size);
603 this->compressed_size = frame->compressed_size;
607 //printf("%d %d %p %p %p %p %p %p\n", w, h, get_y(), get_u(), get_v(), frame->get_y(), frame->get_u(), frame->get_v());
608 memcpy(get_y(), frame->get_y(), w * h);
609 memcpy(get_u(), frame->get_u(), w * h / 4);
610 memcpy(get_v(), frame->get_v(), w * h / 4);
614 //printf("%d %d %p %p %p %p %p %p\n", w, h, get_y(), get_u(), get_v(), frame->get_y(), frame->get_u(), frame->get_v());
615 memcpy(get_y(), frame->get_y(), w * h);
616 memcpy(get_u(), frame->get_u(), w * h / 2);
617 memcpy(get_v(), frame->get_v(), w * h / 2);
621 // printf("VFrame::copy_from %d\n", calculate_data_size(w,
624 // frame->color_model));
625 memcpy(data, frame->data, calculate_data_size(w,
628 frame->color_model));
636 #define OVERLAY(type, max, components) \
638 type **in_rows = (type**)src->get_rows(); \
639 type **out_rows = (type**)get_rows(); \
640 int in_w = src->get_w(); \
641 int in_h = src->get_h(); \
643 for(int i = 0; i < in_h; i++) \
645 if(i + out_y1 >= 0 && i + out_y1 < h) \
647 type *src_row = in_rows[i]; \
648 type *dst_row = out_rows[i + out_y1] + out_x1 * components; \
650 for(int j = 0; j < in_w; j++) \
652 if(j + out_x1 >= 0 && j + out_x1 < w) \
654 int opacity = src_row[3]; \
655 int transparency = max - src_row[3]; \
656 dst_row[0] = (transparency * dst_row[0] + opacity * src_row[0]) / max; \
657 dst_row[1] = (transparency * dst_row[1] + opacity * src_row[1]) / max; \
658 dst_row[2] = (transparency * dst_row[2] + opacity * src_row[2]) / max; \
659 dst_row[3] = MAX(dst_row[3], src_row[3]); \
662 dst_row += components; \
663 src_row += components; \
670 void VFrame::overlay(VFrame *src,
674 switch(get_color_model())
677 OVERLAY(unsigned char, 0xff, 4);
684 int VFrame::get_scale_tables(int *column_table, int *row_table,
685 int in_x1, int in_y1, int in_x2, int in_y2,
686 int out_x1, int out_y1, int out_x2, int out_y2)
689 float w_in = in_x2 - in_x1;
690 float h_in = in_y2 - in_y1;
691 int w_out = out_x2 - out_x1;
692 int h_out = out_y2 - out_y1;
694 float hscale = w_in / w_out;
695 float vscale = h_in / h_out;
697 for(i = 0; i < w_out; i++)
699 column_table[i] = (int)(hscale * i);
702 for(i = 0; i < h_out; i++)
704 row_table[i] = (int)(vscale * i) + in_y1;
709 int VFrame::get_bytes_per_pixel()
711 return bytes_per_pixel;
714 unsigned char** VFrame::get_rows()
733 int VFrame::get_w_fixed()
738 int VFrame::get_h_fixed()
743 unsigned char* VFrame::get_y()
748 unsigned char* VFrame::get_u()
753 unsigned char* VFrame::get_v()
758 void VFrame::set_number(long number)
760 sequence_number = number;
763 long VFrame::get_number()
765 return sequence_number;