add scaled icon data
[goodguy/history.git] / cinelerra-5.0 / guicast / vframe.C
index a3b09324bd6f59f5e5122874fd82094615925054..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)
+{
+       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()
 {
-       reset_parameters(1);
-       params = new BC_Hash;
-       read_png(png_data, image_size);
 }
 
+
 VFrame::VFrame(VFrame &frame)
 {
        reset_parameters(1);
@@ -220,6 +227,7 @@ int VFrame::params_match(int w, int h, int color_model)
 
 int VFrame::reset_parameters(int do_opengl)
 {
+       status = 1;
        scene = 0;
        field2_offset = -1;
        memory_type = VFrame::PRIVATE;
@@ -661,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] == ' ') {
@@ -686,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);
 
@@ -752,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);
@@ -1042,6 +1049,7 @@ int VFrame::transfer_from(VFrame *that, int bg_color)
                return this->copy_from(that);
 
        timestamp = that->timestamp;
+#if 0
        BC_CModels::transfer(
                this->get_rows(), that->get_rows(),          // Packed data out/in
                this->get_y(), this->get_u(), this->get_v(), // Planar data out/in
@@ -1051,6 +1059,33 @@ int VFrame::transfer_from(VFrame *that, int bg_color)
                that->get_color_model(), this->get_color_model(), // Color models in/out
                bg_color,                                    // alpha blend bg_color
                that->get_w(), this->get_w());               // rowspans (of luma for YUV)
+#else
+       unsigned char *in_ptrs[4], *out_ptrs[4];
+       unsigned char **inp, **outp;
+       if( BC_CModels::is_planar(that->get_color_model()) ) {
+               in_ptrs[0] = that->get_y();
+               in_ptrs[1] = that->get_u();
+               in_ptrs[2] = that->get_v();
+               in_ptrs[3] = that->get_a();
+               inp = in_ptrs;
+       }
+       else
+               inp = that->get_rows(); 
+       if( BC_CModels::is_planar(this->get_color_model()) ) {
+               out_ptrs[0] = this->get_y();
+               out_ptrs[1] = this->get_u();
+               out_ptrs[2] = this->get_v();
+               out_ptrs[3] = this->get_a();
+               outp = out_ptrs;
+       }
+       else
+               outp = this->get_rows();        
+       BC_CModels::transfer(outp, this->get_color_model(),
+                       0, 0, this->get_w(), this->get_h(), this->get_w(),
+               inp, that->get_color_model(),
+                       0, 0, that->get_w(), that->get_h(), that->get_w(),
+               bg_color);
+#endif
        return 0;
 }
 
@@ -1187,12 +1222,13 @@ void VFrame::clear_stacks()
 {
        next_effects.remove_all_objects();
        prev_effects.remove_all_objects();
-       delete params;
-       params = new BC_Hash;
+       params->clear();
+       status = 1;
 }
 
 void VFrame::copy_params(VFrame *src)
 {
+       status = src->status;
        params->copy_from(src->params);
 }
 
@@ -1213,7 +1249,7 @@ void VFrame::copy_stacks(VFrame *src)
                strcpy(ptr, src->prev_effects.values[i]);
        }
 
-       params->copy_from(src->params);
+       copy_params(src);
 }
 
 int VFrame::equal_stacks(VFrame *src)
@@ -1255,84 +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) * 12 + 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;
-       *(long*)(buffer + 44) = 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);
-       sequence_number = *(long*)(buffer + 44);
-//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);
+}