//static BCCounter counter;
-VFrame::VFrame(unsigned char *png_data)
+VFramePng::VFramePng(unsigned char *png_data, double scale)
{
- reset_parameters(1);
- params = new BC_Hash;
- read_png(png_data);
+ long image_size =
+ ((long)png_data[0] << 24) | ((long)png_data[1] << 16) |
+ ((long)png_data[2] << 8) | (long)png_data[3];
+ if( !scale ) scale = BC_WindowBase::get_resources()->icon_scale;
+ read_png(png_data+4, image_size, scale, scale);
}
-VFrame::VFrame(unsigned char *png_data, long image_size)
+VFramePng::VFramePng(unsigned char *png_data, long image_size, double xscale, double yscale)
{
- reset_parameters(1);
- params = new BC_Hash;
- read_png(png_data, image_size);
+ if( !xscale ) xscale = BC_WindowBase::get_resources()->icon_scale;
+ if( !yscale ) yscale = BC_WindowBase::get_resources()->icon_scale;
+ read_png(png_data, image_size, xscale, yscale);
}
+VFramePng::~VFramePng()
+{
+}
+
+
VFrame::VFrame(VFrame &frame)
{
reset_parameters(1);
return 0;
}
-int VFrame::read_png(const unsigned char *data, long img_sz)
+int VFramePng::read_png(const unsigned char *data, long sz, double xscale, double yscale)
{
// Test for RAW format
if(data[0] == 'R' && data[1] == 'A' && data[2] == 'W' && data[3] == ' ') {
int new_color_model;
image_offset = 0;
- image = data; image_size = img_sz;
+ image = data; image_size = sz;
png_set_read_fn(png_ptr, this, PngReadFunction::png_read_function);
png_read_info(png_ptr, info_ptr);
printf("VFrame::read_png %d: unknown file format"
" 0x%02x 0x%02x 0x%02x 0x%02x\n",
__LINE__, data[4], data[5], data[6], data[7]);
+ return 1;
+ }
+ int ww = w * xscale, hh = h * yscale;
+ if( ww != w || hh != h ) {
+ VFrame vframe(*this);
+ reallocate(NULL, -1, 0, 0, 0, ww, hh, color_model, -1);
+ transfer_from(&vframe);
}
return 0;
}
-int VFrame::read_png(const unsigned char *data)
-{
- long img_sz =
- ((long)data[0] << 24) | ((long)data[1] << 16) |
- ((long)data[2] << 8) | (long)data[3];
- return read_png(data+4, img_sz);
-}
-
int VFrame::write_png(const char *path)
{
png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
w, h, color_model, rows, use_shm, shmid);
}
-int VFrame::filefork_size()
+
+int VFrame::get_memory_usage()
{
- return sizeof(int) * 13 + sizeof(long);
+ if(get_compressed_allocated()) return get_compressed_allocated();
+ return get_h() * get_bytes_per_line();
}
-
-void VFrame::to_filefork(unsigned char *buffer)
+void VFrame::draw_pixel(int x, int y)
{
- *(int*)(buffer + 0) = shmid;
- *(int*)(buffer + 4) = y_offset;
- *(int*)(buffer + 8) = u_offset;
- *(int*)(buffer + 12) = v_offset;
- *(int*)(buffer + 16) = w;
- *(int*)(buffer + 20) = h;
- *(int*)(buffer + 24) = color_model;
- *(int*)(buffer + 28) = bytes_per_line;
- *(int*)(buffer + 32) = compressed_allocated;
- *(int*)(buffer + 36) = compressed_size;
- *(int*)(buffer + 40) = is_keyframe;
- *(int*)(buffer + 44) = status;
- *(long*)(buffer + 48) = sequence_number;
+ if(!(x >= 0 && y >= 0 && x < get_w() && y < get_h())) return;
+#define DRAW_PIXEL(x, y, components, do_yuv, max, type) \
+{ \
+ type **rows = (type**)get_rows(); \
+ rows[y][x * components] = max - rows[y][x * components]; \
+ if(!do_yuv) \
+ { \
+ rows[y][x * components + 1] = max - rows[y][x * components + 1]; \
+ rows[y][x * components + 2] = max - rows[y][x * components + 2]; \
+ } \
+ else \
+ { \
+ rows[y][x * components + 1] = (max / 2 + 1) - rows[y][x * components + 1]; \
+ rows[y][x * components + 2] = (max / 2 + 1) - rows[y][x * components + 2]; \
+ } \
+ if(components == 4) \
+ rows[y][x * components + 3] = max; \
+}
-//printf("VFrame::to_filefork %d %lld\n", __LINE__, sequence_number);
-// printf("VFrame::to_filefork %d", __LINE__);
-// for(int i = 0; i < 40; i++)
-// {
-// printf(" %02x", buffer[i]);
-// }
-// printf("\n");
-// dump();
+
+ switch(get_color_model())
+ {
+ case BC_RGB888:
+ DRAW_PIXEL(x, y, 3, 0, 0xff, unsigned char);
+ break;
+ case BC_RGBA8888:
+ DRAW_PIXEL(x, y, 4, 0, 0xff, unsigned char);
+ break;
+ case BC_RGB_FLOAT:
+ DRAW_PIXEL(x, y, 3, 0, 1.0, float);
+ break;
+ case BC_RGBA_FLOAT:
+ DRAW_PIXEL(x, y, 4, 0, 1.0, float);
+ break;
+ case BC_YUV888:
+ DRAW_PIXEL(x, y, 3, 1, 0xff, unsigned char);
+ break;
+ case BC_YUVA8888:
+ DRAW_PIXEL(x, y, 4, 1, 0xff, unsigned char);
+ break;
+ case BC_RGB161616:
+ DRAW_PIXEL(x, y, 3, 0, 0xffff, uint16_t);
+ break;
+ case BC_YUV161616:
+ DRAW_PIXEL(x, y, 3, 1, 0xffff, uint16_t);
+ break;
+ case BC_RGBA16161616:
+ DRAW_PIXEL(x, y, 4, 0, 0xffff, uint16_t);
+ break;
+ case BC_YUVA16161616:
+ DRAW_PIXEL(x, y, 4, 1, 0xffff, uint16_t);
+ break;
+ }
}
-void VFrame::from_filefork(unsigned char *buffer)
+void VFrame::draw_line(int x1, int y1, int x2, int y2)
{
-// This frame will always be preallocated shared memory
-//printf("VFrame::from_filefork %d %d\n", __LINE__, *(int*)(buffer + 24));
- if(*(int*)(buffer + 24) == BC_COMPRESSED)
- {
- set_compressed_memory(0,
- *(int*)(buffer + 0), // shmid
- *(int*)(buffer + 36), // compressed_size
- *(int*)(buffer + 32)); // compressed_allocated
- color_model = BC_COMPRESSED;
-//printf("VFrame::from_filefork %d %d\n", __LINE__, get_compressed_size());
+ int w = labs(x2 - x1);
+ int h = labs(y2 - y1);
+//printf("FindObjectMain::draw_line 1 %d %d %d %d\n", x1, y1, x2, y2);
+ if(!w && !h)
+ {
+ draw_pixel(x1, y1);
}
else
+ if(w > h)
{
-// printf("VFrame::from_filefork %d", __LINE__);
-// for(int i = 0; i < 40; i++)
-// {
-// printf(" %02x", buffer[i]);
-// }
-// printf("\n");
- reallocate(0,
- *(int*)(buffer + 0), // shmid
- *(int*)(buffer + 4), // y_offset
- *(int*)(buffer + 8), // u_offset
- *(int*)(buffer + 12), // v_offset
- *(int*)(buffer + 16), // w
- *(int*)(buffer + 20), // h
- *(int*)(buffer + 24), // colormodel
- *(int*)(buffer + 28)); // bytes per line
-//dump();
+// Flip coordinates so x1 < x2
+ if(x2 < x1)
+ {
+ y2 ^= y1;
+ y1 ^= y2;
+ y2 ^= y1;
+ x1 ^= x2;
+ x2 ^= x1;
+ x1 ^= x2;
+ }
+ int numerator = y2 - y1;
+ int denominator = x2 - x1;
+ for(int i = x1; i <= x2; i++)
+ {
+ int y = y1 + (int64_t)(i - x1) * (int64_t)numerator / (int64_t)denominator;
+ draw_pixel(i, y);
+ }
}
-
- is_keyframe = *(int*)(buffer + 40);
- status = *(int*)(buffer + 44);
- sequence_number = *(long*)(buffer + 48);
-//printf("VFrame::from_filefork %d %lld\n", __LINE__, sequence_number);
+ else
+ {
+// Flip coordinates so y1 < y2
+ if(y2 < y1)
+ {
+ y2 ^= y1;
+ y1 ^= y2;
+ y2 ^= y1;
+ x1 ^= x2;
+ x2 ^= x1;
+ x1 ^= x2;
+ }
+ int numerator = x2 - x1;
+ int denominator = y2 - y1;
+ for(int i = y1; i <= y2; i++)
+ {
+ int x = x1 + (int64_t)(i - y1) * (int64_t)numerator / (int64_t)denominator;
+ draw_pixel(x, i);
+ }
+ }
+//printf("FindObjectMain::draw_line 2\n");
}
-int VFrame::get_memory_usage()
+void VFrame::draw_rect(int x1, int y1, int x2, int y2)
{
- if(get_compressed_allocated()) return get_compressed_allocated();
- return get_h() * get_bytes_per_line();
+ draw_line(x1, y1, x2, y1);
+ draw_line(x2, y1 + 1, x2, y2);
+ draw_line(x2 - 1, y2, x1, y2);
+ draw_line(x1, y2 - 1, x1, y1 + 1);
}
+#define ARROW_SIZE 10
+void VFrame::draw_arrow(int x1, int y1, int x2, int y2)
+{
+ double angle = atan((float)(y2 - y1) / (float)(x2 - x1));
+ double angle1 = angle + (float)145 / 360 * 2 * 3.14159265;
+ double angle2 = angle - (float)145 / 360 * 2 * 3.14159265;
+ int x3;
+ int y3;
+ int x4;
+ int y4;
+ if(x2 < x1)
+ {
+ x3 = x2 - (int)(ARROW_SIZE * cos(angle1));
+ y3 = y2 - (int)(ARROW_SIZE * sin(angle1));
+ x4 = x2 - (int)(ARROW_SIZE * cos(angle2));
+ y4 = y2 - (int)(ARROW_SIZE * sin(angle2));
+ }
+ else
+ {
+ x3 = x2 + (int)(ARROW_SIZE * cos(angle1));
+ y3 = y2 + (int)(ARROW_SIZE * sin(angle1));
+ x4 = x2 + (int)(ARROW_SIZE * cos(angle2));
+ y4 = y2 + (int)(ARROW_SIZE * sin(angle2));
+ }
+
+// Main vector
+ draw_line(x1, y1, x2, y2);
+// draw_line(x1, y1 + 1, x2, y2 + 1);
+
+// Arrow line
+ if(abs(y2 - y1) || abs(x2 - x1)) draw_line(x2, y2, x3, y3);
+// Arrow line
+ if(abs(y2 - y1) || abs(x2 - x1)) draw_line(x2, y2, x4, y4);
+}