folder icon move segv, resources drag scroll bug, memory leaks, global msgqual, po...
[goodguy/history.git] / cinelerra-5.1 / guicast / vframe.C
index aadd6a721dc540205f1fb018bc6727219d51bd47..2573e56b334af163db07d684965901fbf49c3248 100644 (file)
@@ -127,15 +127,13 @@ VFrame *VFramePng::vframe_png(const char *png_path, double xs, double ys)
        return vframe;
 }
 
-
 VFrame::VFrame(VFrame &frame)
 {
        reset_parameters(1);
        params = new BC_Hash;
        allocate_data(0, -1, 0, 0, 0, frame.w, frame.h,
                frame.color_model, frame.bytes_per_line);
-       memcpy(data, frame.data, bytes_per_line * h);
-       copy_stacks(&frame);
+       copy_from(&frame);
 }
 
 VFrame::VFrame(int w, int h, int color_model, long bytes_per_line)
@@ -306,6 +304,11 @@ int VFrame::clear_objects(int do_opengl)
                pbuffer = 0;
        }
 
+#ifdef LEAKER
+if( memory_type != VFrame::SHARED )
+  printf("==del %p from %p\n", data, __builtin_return_address(0));
+#endif
+
 // Delete data
        switch(memory_type)
        {
@@ -524,6 +527,9 @@ int VFrame::allocate_data(unsigned char *data, int shmid,
 
                if(!this->data)
                        printf("VFrame::allocate_data %dx%d: memory exhausted.\n", this->w, this->h);
+#ifdef LEAKER
+printf("==new %p from %p sz %d\n", this->data, __builtin_return_address(0), size);
+#endif
 
 //printf("VFrame::allocate_data %d %p data=%p %d %d\n", __LINE__, this, this->data, this->w, this->h);
 //if(size > 1000000) printf("VFrame::allocate_data %d\n", size);
@@ -807,49 +813,41 @@ int VFramePng::read_png(const unsigned char *data, long sz, double xscale, doubl
 
 int VFrame::write_png(const char *path)
 {
+       VFrame *vframe = this;
        png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
        png_infop info_ptr = png_create_info_struct(png_ptr);
        FILE *out_fd = fopen(path, "w");
-       if(!out_fd)
-       {
+       if(!out_fd) {
                printf("VFrame::write_png %d %s %s\n", __LINE__, path, strerror(errno));
                return 1;
        }
 
        int png_cmodel = PNG_COLOR_TYPE_RGB;
-       switch(get_color_model())
-       {
-               case BC_RGB888:
-               case BC_YUV888:
-                       png_cmodel = PNG_COLOR_TYPE_RGB;
-                       break;
-
-               case BC_RGBA8888:
-               case BC_YUVA8888:
+       int bc_cmodel = get_color_model();
+       switch( bc_cmodel ) {
+       case BC_RGB888:                                          break;
+       case BC_RGBA8888: png_cmodel = PNG_COLOR_TYPE_RGB_ALPHA; break;
+       case BC_A8:       png_cmodel = PNG_COLOR_TYPE_GRAY;      break;
+       default:
+               bc_cmodel = BC_RGB888;
+               if( BC_CModels::has_alpha(bc_cmodel) ) {
+                       bc_cmodel = BC_RGBA8888;
                        png_cmodel = PNG_COLOR_TYPE_RGB_ALPHA;
-                       break;
-
-               case BC_A8:
-                       png_cmodel = PNG_COLOR_TYPE_GRAY;
-                       break;
+               }
+               vframe = new VFrame(get_w(), get_h(), bc_cmodel, -1);
+               vframe->transfer_from(this);
+               break;
        }
-
        png_init_io(png_ptr, out_fd);
        png_set_compression_level(png_ptr, 9);
-       png_set_IHDR(png_ptr,
-               info_ptr,
-               get_w(),
-               get_h(),
-       8,
-               png_cmodel,
-               PNG_INTERLACE_NONE,
-               PNG_COMPRESSION_TYPE_DEFAULT,
-               PNG_FILTER_TYPE_DEFAULT);
+       png_set_IHDR(png_ptr, info_ptr, get_w(), get_h(), 8, png_cmodel,
+               PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
        png_write_info(png_ptr, info_ptr);
-       png_write_image(png_ptr, get_rows());
+       png_write_image(png_ptr, vframe->get_rows());
        png_write_end(png_ptr, info_ptr);
        png_destroy_write_struct(&png_ptr, &info_ptr);
        fclose(out_fd);
+       if( vframe != this ) delete vframe;
        return 0;
 }
 
@@ -940,12 +938,9 @@ int VFrame::clear_frame()
 void VFrame::rotate90()
 {
 // Allocate new frame
-       int new_w = h, new_h = w, new_bytes_per_line = bytes_per_pixel * new_w;
-       unsigned char *new_data = new unsigned char[calculate_data_size(new_w, new_h, new_bytes_per_line, color_model)];
-       unsigned char **new_rows = new unsigned char*[new_h];
-       for(int i = 0; i < new_h; i++)
-               new_rows[i] = &new_data[new_bytes_per_line * i];
-
+       int new_w = h, new_h = w;
+       VFrame new_frame(new_w, new_h, color_model);
+       unsigned char **new_rows = new_frame.get_rows();
 // Copy data
        for(int in_y = 0, out_x = new_w - 1; in_y < h; in_y++, out_x--)
        {
@@ -960,23 +955,34 @@ void VFrame::rotate90()
        }
 
 // Swap frames
-       clear_objects(0);
+// swap memory
+       unsigned char *new_data = new_frame.data;
+       new_frame.data = data;
        data = new_data;
+// swap rows
+       new_rows = new_frame.rows;
+       new_frame.rows = rows;
        rows = new_rows;
-       bytes_per_line = new_bytes_per_line;
-       w = new_w;
-       h = new_h;
+// swap shmid
+       int new_shmid = new_frame.shmid;
+       new_frame.shmid = shmid;
+       shmid = new_shmid;
+// swap bytes_per_line
+       int new_bpl = new_frame.bytes_per_line;
+       new_frame.bytes_per_line = bytes_per_line;
+       bytes_per_line = new_bpl;
+       new_frame.clear_objects(0);
+
+       w = new_frame.w;
+       h = new_frame.h;
 }
 
 void VFrame::rotate270()
 {
 // Allocate new frame
-       int new_w = h, new_h = w, new_bytes_per_line = bytes_per_pixel * new_w;
-       unsigned char *new_data = new unsigned char[calculate_data_size(new_w, new_h, new_bytes_per_line, color_model)];
-       unsigned char **new_rows = new unsigned char*[new_h];
-       for(int i = 0; i < new_h; i++)
-               new_rows[i] = &new_data[new_bytes_per_line * i];
-
+       int new_w = h, new_h = w;
+       VFrame new_frame(new_w, new_h, color_model);
+       unsigned char **new_rows = new_frame.get_rows();
 // Copy data
        for(int in_y = 0, out_x = 0; in_y < h; in_y++, out_x++)
        {
@@ -991,12 +997,26 @@ void VFrame::rotate270()
        }
 
 // Swap frames
-       clear_objects(0);
+// swap memory
+       unsigned char *new_data = new_frame.data;
+       new_frame.data = data;
        data = new_data;
+// swap rows
+       new_rows = new_frame.rows;
+       new_frame.rows = rows;
        rows = new_rows;
-       bytes_per_line = new_bytes_per_line;
-       w = new_w;
-       h = new_h;
+// swap shmid
+       int new_shmid = new_frame.shmid;
+       new_frame.shmid = shmid;
+       shmid = new_shmid;
+// swap bytes_per_line
+       int new_bpl = new_frame.bytes_per_line;
+       new_frame.bytes_per_line = bytes_per_line;
+       bytes_per_line = new_bpl;
+       new_frame.clear_objects(0);
+
+       w = new_frame.w;
+       h = new_frame.h;
 }
 
 void VFrame::flip_vert()
@@ -1030,6 +1050,18 @@ void VFrame::flip_horiz()
 
 int VFrame::copy_from(VFrame *frame)
 {
+       if(this->w != frame->get_w() ||
+               this->h != frame->get_h())
+       {
+               printf("VFrame::copy_from %d sizes differ src %dx%d != dst %dx%d\n",
+                       __LINE__,
+                       frame->get_w(),
+                       frame->get_h(),
+                       get_w(),
+                       get_h());
+               return 1;
+       }
+
        int w = MIN(this->w, frame->get_w());
        int h = MIN(this->h, frame->get_h());
        timestamp = frame->timestamp;
@@ -1080,6 +1112,7 @@ int VFrame::copy_from(VFrame *frame)
                        break;
        }
 
+       params->copy_from(frame->params);
        return 0;
 }
 
@@ -1131,6 +1164,7 @@ int VFrame::transfer_from(VFrame *that, int bg_color, int in_x, int in_y, int in
                        that->get_bytes_per_line(),
                bg_color);
 #endif
+       params->copy_from(that->params);
        return 0;
 }
 
@@ -1638,6 +1672,7 @@ void VFrame::smooth_draw(int x1, int y1, int x2, int y2, int x3, int y3)
        }
 }
 
+
 void VFrame::draw_rect(int x1, int y1, int x2, int y2)
 {
        draw_line(x1, y1, x2, y1);
@@ -1646,6 +1681,52 @@ void VFrame::draw_rect(int x1, int y1, int x2, int y2)
        draw_line(x1, y2 - 1, x1, y1 + 1);
 }
 
+
+void VFrame::draw_oval(int x1, int y1, int x2, int y2)
+{
+       int w = x2 - x1;
+       int h = y2 - y1;
+       int center_x = (x2 + x1) / 2;
+       int center_y = (y2 + y1) / 2;
+       int x_table[h / 2];
+
+//printf("VFrame::draw_oval %d %d %d %d %d\n", __LINE__, x1, y1, x2, y2);
+
+       for(int i = 0; i < h / 2; i++) {
+// A^2 = -(B^2) + C^2
+               x_table[i] = (int)(sqrt(-SQR(h / 2 - i) + SQR(h / 2)) * w / h);
+//printf("VFrame::draw_oval %d i=%d x=%d\n", __LINE__, i, x_table[i]);
+       }
+
+       for(int i = 0; i < h / 2 - 1; i++) {
+               int x3 = x_table[i];
+               int x4 = x_table[i + 1];
+
+               if(x4 > x3 + 1) {
+                       for(int j = x3; j < x4; j++) {
+                               draw_pixel(center_x + j, y1 + i);
+                               draw_pixel(center_x - j, y1 + i);
+                               draw_pixel(center_x + j, y2 - i - 1);
+                               draw_pixel(center_x - j, y2 - i - 1);
+                       }
+               }
+               else {
+                       draw_pixel(center_x + x3, y1 + i);
+                       draw_pixel(center_x - x3, y1 + i);
+                       draw_pixel(center_x + x3, y2 - i - 1);
+                       draw_pixel(center_x - x3, y2 - i - 1);
+               }
+       }
+       
+       draw_pixel(center_x, y1);
+       draw_pixel(center_x, y2 - 1);
+       draw_pixel(x1, center_y);
+       draw_pixel(x2 - 1, center_y);
+       draw_pixel(x1, center_y - 1);
+       draw_pixel(x2 - 1, center_y - 1);
+}
+
+
 void VFrame::draw_arrow(int x1, int y1, int x2, int y2, int sz)
 {
        double angle = atan((float)(y2 - y1) / (float)(x2 - x1));