add scaled icon data
[goodguy/history.git] / cinelerra-5.0 / guicast / vframe.C
index de53a068a70b95196007305093c722fefa91e905..1eec314bb0c7757468a98cdb23f65953cd10934e 100644 (file)
@@ -79,20 +79,27 @@ VFrameScene::~VFrameScene()
 //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);
@@ -662,7 +669,7 @@ UNBUFFER(data);
        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] == ' ') {
@@ -687,7 +694,7 @@ int VFrame::read_png(const unsigned char *data, long img_sz)
                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);
 
@@ -753,18 +760,17 @@ int VFrame::read_png(const unsigned char *data, long img_sz)
                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);
@@ -1285,86 +1291,168 @@ void VFrame::dump()
                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);
+}