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(const PngData& png_data)
48 //printf("VFrame::VFrame 1\n");
50 //printf("VFrame::VFrame 1\n");
52 //printf("VFrame::VFrame 2\n");
55 VFrame::VFrame(VFrame &frame)
58 allocate_data(0, 0, 0, 0, frame.w, frame.h, frame.color_model, frame.bytes_per_line);
59 memcpy(data, frame.data, bytes_per_line * h);
63 VFrame::VFrame(unsigned char *data,
70 allocate_data(data, 0, 0, 0, w, h, color_model, bytes_per_line);
74 VFrame::VFrame(unsigned char *data,
98 this->color_model = BC_COMPRESSED;
118 int VFrame::equivalent(VFrame *src)
120 return (src->get_color_model() == get_color_model() &&
121 src->get_w() == get_w() &&
122 src->get_h() == get_h() &&
123 src->bytes_per_line == bytes_per_line);
126 long VFrame::set_shm_offset(long offset)
132 long VFrame::get_shm_offset()
137 int VFrame::params_match(int w, int h, int color_model)
139 return (this->w == w &&
141 this->color_model == color_model);
145 int VFrame::reset_parameters()
154 compressed_allocated = 0;
155 compressed_size = 0; // Size of current image
162 sequence_number = -1;
167 int VFrame::clear_objects()
170 //printf("VFrame::clear_objects 1 %p %d\n", this, shared);
173 int size = calculate_data_size(this->w, this->h, this->bytes_per_line, this->color_model);
174 if(size > 2560 * 1920)
176 if(data) delete [] data;
180 // Delete row pointers
195 int VFrame::get_field2_offset()
197 return field2_offset;
200 int VFrame::set_field2_offset(int value)
202 this->field2_offset = value;
206 void VFrame::set_keyframe(int value)
208 this->is_keyframe = value;
211 int VFrame::get_keyframe()
217 int VFrame::calculate_bytes_per_pixel(int color_model)
219 return cmodel_calculate_pixelsize(color_model);
222 long VFrame::get_bytes_per_line()
224 return bytes_per_line;
227 long VFrame::get_data_size()
229 return calculate_data_size(w, h, bytes_per_line, color_model) - 4;
230 // return h * bytes_per_line;
233 long VFrame::calculate_data_size(int w, int h, int bytes_per_line, int color_model)
235 return cmodel_calculate_datasize(w, h, bytes_per_line, color_model);
239 void VFrame::create_row_pointers()
248 this->u_offset = w * h;
249 this->v_offset = w * h + w * h / 4;
251 y = this->data + this->y_offset;
252 u = this->data + this->u_offset;
253 v = this->data + this->v_offset;
260 this->u_offset = w * h;
261 this->v_offset = w * h + w * h / 2;
263 y = this->data + this->y_offset;
264 u = this->data + this->u_offset;
265 v = this->data + this->v_offset;
269 rows = new unsigned char*[h];
270 for(int i = 0; i < h; i++)
272 rows[i] = &this->data[i * this->bytes_per_line];
278 int VFrame::allocate_data(unsigned char *data,
289 this->color_model = color_model;
290 this->bytes_per_pixel = calculate_bytes_per_pixel(color_model);
291 this->y_offset = this->u_offset = this->v_offset = 0;
293 if(bytes_per_line >= 0)
295 this->bytes_per_line = bytes_per_line;
298 this->bytes_per_line = this->bytes_per_pixel * w;
300 // Allocate data + padding for MMX
305 this->y_offset = y_offset;
306 this->u_offset = u_offset;
307 this->v_offset = v_offset;
312 int size = calculate_data_size(this->w,
314 this->bytes_per_line,
316 this->data = new unsigned char[size];
318 if(size > 2560 * 1920)
319 BUFFER(size, this->data, "VFrame::allocate_data");
322 printf("VFrame::allocate_data %dx%d: memory exhausted.\n", this->w, this->h);
324 //printf("VFrame::allocate_data %p %d %d\n", this, this->w, this->h);
325 //if(size > 1000000) printf("VFrame::allocate_data %d\n", size);
328 // Create row pointers
329 create_row_pointers();
333 void VFrame::set_memory(unsigned char *data,
340 this->y_offset = y_offset;
341 this->u_offset = u_offset;
342 this->v_offset = v_offset;
343 y = this->data + this->y_offset;
344 u = this->data + this->u_offset;
345 v = this->data + this->v_offset;
346 create_row_pointers();
349 void VFrame::set_compressed_memory(unsigned char *data,
356 this->compressed_allocated = data_allocated;
357 this->compressed_size = data_size;
361 // Reallocate uncompressed buffer with or without alpha
362 int VFrame::reallocate(unsigned char *data,
384 int VFrame::allocate_compressed_data(long bytes)
386 if(bytes < 1) return 1;
388 // Want to preserve original contents
389 if(data && compressed_allocated < bytes)
391 unsigned char *new_data = new unsigned char[bytes];
392 bcopy(data, new_data, compressed_allocated);
395 compressed_allocated = bytes;
400 data = new unsigned char[bytes];
401 compressed_allocated = bytes;
408 int VFrame::read_png(unsigned char *data)
411 d.size = (((unsigned long)data[0]) << 24) |
412 (((unsigned long)data[1]) << 16) |
413 (((unsigned long)data[2]) << 8) |
414 (unsigned char)data[3];
419 int VFrame::read_png(const PngData& data)
421 png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
422 png_infop info_ptr = png_create_info_struct(png_ptr);
427 image_size = data.size;
428 png_set_read_fn(png_ptr, this, PngReadFunction::png_read_function);
429 png_read_info(png_ptr, info_ptr);
431 w = png_get_image_width(png_ptr, info_ptr);
432 h = png_get_image_height(png_ptr, info_ptr);
434 int src_color_model = png_get_color_type(png_ptr, info_ptr);
435 switch(src_color_model)
437 case PNG_COLOR_TYPE_RGB:
438 new_color_model = BC_RGB888;
442 case PNG_COLOR_TYPE_GRAY_ALPHA:
443 case PNG_COLOR_TYPE_RGB_ALPHA:
445 new_color_model = BC_RGBA8888;
458 png_read_image(png_ptr, get_rows());
462 if(src_color_model == PNG_COLOR_TYPE_GRAY_ALPHA)
464 for(int i = 0; i < get_h(); i++)
466 unsigned char *row = get_rows()[i];
467 unsigned char *out_ptr = row + get_w() * 4 - 4;
468 unsigned char *in_ptr = row + get_w() * 2 - 2;
470 for(int j = get_w() - 1; j >= 0; j--)
472 out_ptr[0] = in_ptr[0];
473 out_ptr[1] = in_ptr[0];
474 out_ptr[2] = in_ptr[0];
475 out_ptr[3] = in_ptr[1];
482 png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
486 unsigned char* VFrame::get_data()
491 long VFrame::get_compressed_allocated()
493 return compressed_allocated;
496 long VFrame::get_compressed_size()
498 return compressed_size;
501 long VFrame::set_compressed_size(long size)
503 compressed_size = size;
507 int VFrame::get_color_model()
513 int VFrame::equals(VFrame *frame)
515 if(frame->data == data)
521 #define ZERO_YUV(components, type, max) \
523 for(int i = 0; i < h; i++) \
525 type *row = (type*)get_rows()[i]; \
526 for(int j = 0; j < w; j++) \
528 row[j * components] = 0; \
529 row[j * components + 1] = (max + 1) / 2; \
530 row[j * components + 2] = (max + 1) / 2; \
531 if(components == 4) row[j * components + 3] = 0; \
536 int VFrame::clear_frame()
544 bzero(data, h * w * 2);
548 ZERO_YUV(3, unsigned char, 0xff);
552 ZERO_YUV(4, unsigned char, 0xff);
556 ZERO_YUV(3, uint16_t, 0xffff);
559 case BC_YUVA16161616:
560 ZERO_YUV(4, uint16_t, 0xffff);
564 bzero(data, h * bytes_per_line);
570 void VFrame::rotate90()
572 // Allocate new frame
573 int new_w = h, new_h = w, new_bytes_per_line = bytes_per_pixel * new_w;
574 unsigned char *new_data = new unsigned char[calculate_data_size(new_w, new_h, new_bytes_per_line, color_model)];
575 unsigned char **new_rows = new unsigned char*[new_h];
576 for(int i = 0; i < new_h; i++)
577 new_rows[i] = &new_data[new_bytes_per_line * i];
580 for(int in_y = 0, out_x = new_w - 1; in_y < h; in_y++, out_x--)
582 for(int in_x = 0, out_y = 0; in_x < w; in_x++, out_y++)
584 for(int k = 0; k < bytes_per_pixel; k++)
586 new_rows[out_y][out_x * bytes_per_pixel + k] =
587 rows[in_y][in_x * bytes_per_pixel + k];
596 bytes_per_line = new_bytes_per_line;
601 void VFrame::rotate270()
603 // Allocate new frame
604 int new_w = h, new_h = w, new_bytes_per_line = bytes_per_pixel * new_w;
605 unsigned char *new_data = new unsigned char[calculate_data_size(new_w, new_h, new_bytes_per_line, color_model)];
606 unsigned char **new_rows = new unsigned char*[new_h];
607 for(int i = 0; i < new_h; i++)
608 new_rows[i] = &new_data[new_bytes_per_line * i];
611 for(int in_y = 0, out_x = 0; in_y < h; in_y++, out_x++)
613 for(int in_x = 0, out_y = new_h - 1; in_x < w; in_x++, out_y--)
615 for(int k = 0; k < bytes_per_pixel; k++)
617 new_rows[out_y][out_x * bytes_per_pixel + k] =
618 rows[in_y][in_x * bytes_per_pixel + k];
627 bytes_per_line = new_bytes_per_line;
632 void VFrame::flip_vert()
634 for(int i = 0, j = h - 1; i < j; i++, j--)
636 for(int k = 0; k < bytes_per_line; k++)
638 unsigned char temp = rows[j][k];
639 rows[j][k] = rows[i][k];
647 int VFrame::copy_from(VFrame *frame)
649 int w = MIN(this->w, frame->get_w());
650 int h = MIN(this->h, frame->get_h());
653 switch(frame->color_model)
656 allocate_compressed_data(frame->compressed_size);
657 memcpy(data, frame->data, frame->compressed_size);
658 this->compressed_size = frame->compressed_size;
662 //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());
663 memcpy(get_y(), frame->get_y(), w * h);
664 memcpy(get_u(), frame->get_u(), w * h / 4);
665 memcpy(get_v(), frame->get_v(), w * h / 4);
669 //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());
670 memcpy(get_y(), frame->get_y(), w * h);
671 memcpy(get_u(), frame->get_u(), w * h / 2);
672 memcpy(get_v(), frame->get_v(), w * h / 2);
676 // printf("VFrame::copy_from %d\n", calculate_data_size(w,
679 // frame->color_model));
680 memcpy(data, frame->data, calculate_data_size(w,
683 frame->color_model));
691 #define OVERLAY(type, max, components) \
693 type **in_rows = (type**)src->get_rows(); \
694 type **out_rows = (type**)get_rows(); \
695 int in_w = src->get_w(); \
696 int in_h = src->get_h(); \
698 for(int i = 0; i < in_h; i++) \
700 if(i + out_y1 >= 0 && i + out_y1 < h) \
702 type *src_row = in_rows[i]; \
703 type *dst_row = out_rows[i + out_y1] + out_x1 * components; \
705 for(int j = 0; j < in_w; j++) \
707 if(j + out_x1 >= 0 && j + out_x1 < w) \
709 int opacity = src_row[3]; \
710 int transparency = max - src_row[3]; \
711 dst_row[0] = (transparency * dst_row[0] + opacity * src_row[0]) / max; \
712 dst_row[1] = (transparency * dst_row[1] + opacity * src_row[1]) / max; \
713 dst_row[2] = (transparency * dst_row[2] + opacity * src_row[2]) / max; \
714 dst_row[3] = MAX(dst_row[3], src_row[3]); \
717 dst_row += components; \
718 src_row += components; \
725 void VFrame::overlay(VFrame *src,
729 switch(get_color_model())
732 OVERLAY(unsigned char, 0xff, 4);
739 int VFrame::get_scale_tables(int *column_table, int *row_table,
740 int in_x1, int in_y1, int in_x2, int in_y2,
741 int out_x1, int out_y1, int out_x2, int out_y2)
744 float w_in = in_x2 - in_x1;
745 float h_in = in_y2 - in_y1;
746 int w_out = out_x2 - out_x1;
747 int h_out = out_y2 - out_y1;
749 float hscale = w_in / w_out;
750 float vscale = h_in / h_out;
752 for(i = 0; i < w_out; i++)
754 column_table[i] = (int)(hscale * i);
757 for(i = 0; i < h_out; i++)
759 row_table[i] = (int)(vscale * i) + in_y1;
764 int VFrame::get_bytes_per_pixel()
766 return bytes_per_pixel;
769 unsigned char** VFrame::get_rows()
788 int VFrame::get_w_fixed()
793 int VFrame::get_h_fixed()
798 unsigned char* VFrame::get_y()
803 unsigned char* VFrame::get_u()
808 unsigned char* VFrame::get_v()
813 void VFrame::set_number(long number)
815 sequence_number = number;
818 long VFrame::get_number()
820 return sequence_number;