From: Good Guy Date: Sat, 16 Dec 2017 16:19:22 +0000 (-0700) Subject: segv in reosurce constructor, add histeq plugin, 2pass formats, cleanup, colormatrix... X-Git-Url: https://cinelerra-gg.org/git/?a=commitdiff_plain;h=4c463964715f67d36cc3ecb92f414cb9f7ba720d;p=goodguy%2Fhistory.git segv in reosurce constructor, add histeq plugin, 2pass formats, cleanup, colormatrix tweaks, fixes --- diff --git a/cinelerra-5.1/cinelerra/appearanceprefs.C b/cinelerra-5.1/cinelerra/appearanceprefs.C index 7342e3ea..0960bb30 100644 --- a/cinelerra-5.1/cinelerra/appearanceprefs.C +++ b/cinelerra-5.1/cinelerra/appearanceprefs.C @@ -135,6 +135,12 @@ void AppearancePrefs::create_objects() x, y)); x = x0; y += 35; + add_subwindow(new BC_Bar(5, y, get_w()/2 - 30)); + y += 15; + + add_subwindow(new BC_Title(x, y, _("Color:"), LARGEFONT, + resources->text_default)); + y += 35; add_subwindow(title = new BC_Title(x, y, _("Highlighting Inversion color:"))); x += title->get_w() + margin; char hex_color[BCSTRLEN]; diff --git a/cinelerra-5.1/cinelerra/awindowgui.C b/cinelerra-5.1/cinelerra/awindowgui.C index 7195d4e7..a0b7d385 100644 --- a/cinelerra-5.1/cinelerra/awindowgui.C +++ b/cinelerra-5.1/cinelerra/awindowgui.C @@ -106,14 +106,14 @@ VFrame *AssetVIcon::frame() delete temp; temp = 0; } if( !temp ) - temp = new VFrame(asset->width, asset->height, BC_RGB888, 0); + temp = new VFrame(0, -1, asset->width, asset->height, BC_RGB888, -1); int ww = picon->gui->vicon_thread->view_w; int hh = picon->gui->vicon_thread->view_h; while( seq_no >= images.size() ) { file->set_layer(0); int64_t pos = images.size() / picon->gui->vicon_thread->refresh_rate * frame_rate; file->set_video_position(pos,0); - file->read_frame(temp); + if( file->read_frame(temp) ) temp->clear_frame(); add_image(temp, ww, hh, BC_RGB8); } mwindow->video_cache->check_in(asset); diff --git a/cinelerra-5.1/cinelerra/filebase.C b/cinelerra-5.1/cinelerra/filebase.C index 29813196..4671fc4a 100644 --- a/cinelerra-5.1/cinelerra/filebase.C +++ b/cinelerra-5.1/cinelerra/filebase.C @@ -42,26 +42,20 @@ FileBase::FileBase(Asset *asset, File *file) FileBase::~FileBase() { close_file(); - if(row_pointers_in) delete [] row_pointers_in; - if(row_pointers_out) delete [] row_pointers_out; - if(float_buffer) delete [] float_buffer; } int FileBase::close_file() { - if(row_pointers_in) delete [] row_pointers_in; - if(row_pointers_out) delete [] row_pointers_out; - if(float_buffer) delete [] float_buffer; + delete [] row_pointers_in; row_pointers_in = 0; + delete [] row_pointers_out; row_pointers_out = 0; + delete [] float_buffer; float_buffer = 0; - - if(pcm_history) - { + if( pcm_history ) { for(int i = 0; i < history_channels; i++) delete [] pcm_history[i]; - delete [] pcm_history; + delete [] pcm_history; pcm_history = 0; } - close_file_derived(); reset_parameters(); return 0; @@ -72,8 +66,7 @@ void FileBase::update_pcm_history(int64_t len) decode_start = 0; decode_len = 0; - if(!pcm_history) - { + if( !pcm_history ) { history_channels = asset->channels; pcm_history = new double*[history_channels]; for(int i = 0; i < history_channels; i++) diff --git a/cinelerra-5.1/cinelerra/filecr2.C b/cinelerra-5.1/cinelerra/filecr2.C index f7466a0c..f7db2f01 100644 --- a/cinelerra-5.1/cinelerra/filecr2.C +++ b/cinelerra-5.1/cinelerra/filecr2.C @@ -196,7 +196,7 @@ int FileCR2::get_best_colormodel(Asset *asset, int driver) // int64_t FileCR2::get_memory_usage() // { // int64_t result = asset->width * asset->height * sizeof(float) * 3; -//printf("FileCR2::get_memory_usage %d " _LD "\n", __LINE__, result); +//printf("FileCR2::get_memory_usage %d %jd\n", __LINE__, result); // return result; // } diff --git a/cinelerra-5.1/cinelerra/filempeg.C b/cinelerra-5.1/cinelerra/filempeg.C index 4617fe3f..9913a98b 100644 --- a/cinelerra-5.1/cinelerra/filempeg.C +++ b/cinelerra-5.1/cinelerra/filempeg.C @@ -786,7 +786,7 @@ int FileMPEG::toc_nail(void *vp, int track) if( mpeg->get_video_info(track, pid, framerate, width, height) ) return 1; if( pid < 0 || framerate <= 0 ) return 1; double position = framenum / framerate; -//printf("t%d/%03x f"_LD", %dx%d %dx%d\n",track,pid,framenum,mw,mh,width,height); +//printf("t%d/%03x f%jd, %dx%d %dx%d\n",track,pid,framenum,mw,mh,width,height); MWindow::commercials->get_frame(file, pid, position, tdat, mw, mh, width, height); return 0; } diff --git a/cinelerra-5.1/cinelerra/mainindexes.C b/cinelerra-5.1/cinelerra/mainindexes.C index 679441bd..d871a50b 100644 --- a/cinelerra-5.1/cinelerra/mainindexes.C +++ b/cinelerra-5.1/cinelerra/mainindexes.C @@ -74,8 +74,7 @@ void MainIndexes::add_next_asset(File *file, Indexable *indexable) SET_TRACE // Test current asset IndexFile indexfile(mwindow, indexable); - IndexState *index_state = 0; - index_state = indexable->index_state; + IndexState *index_state = indexable->index_state; SET_TRACE int ret = indexfile.open_index(); diff --git a/cinelerra-5.1/cinelerra/mwindow.C b/cinelerra-5.1/cinelerra/mwindow.C index 84ba6830..31790067 100644 --- a/cinelerra-5.1/cinelerra/mwindow.C +++ b/cinelerra-5.1/cinelerra/mwindow.C @@ -3352,6 +3352,7 @@ void MWindow::rebuild_indices() asset->reset_audio(); } asset->reset_video(); + remove_asset_from_caches(asset); // File file; // re-probe the asset // file.open_file(preferences, asset, 1, 0); } diff --git a/cinelerra-5.1/cinelerra/performanceprefs.inc b/cinelerra-5.1/cinelerra/performanceprefs.inc index 6e9a2a4a..b8793fb1 100644 --- a/cinelerra-5.1/cinelerra/performanceprefs.inc +++ b/cinelerra-5.1/cinelerra/performanceprefs.inc @@ -28,8 +28,6 @@ class PrefsBRenderFragment; class PrefsRenderPreroll; class PrefsBRenderPreroll; class PrefsForceUniprocessor; -class PrefsTrapSigSEGV; -class PrefsTrapSigINTR; class PrefsFFMPEGMarkerIndecies; class PrefsRenderFarm; class PrefsRenderFarmConsolidate; diff --git a/cinelerra-5.1/cinelerra/playback3d.h b/cinelerra-5.1/cinelerra/playback3d.h index 452b367c..2139ba7b 100644 --- a/cinelerra-5.1/cinelerra/playback3d.h +++ b/cinelerra-5.1/cinelerra/playback3d.h @@ -42,7 +42,7 @@ // use static presets YUV in bccolors.h #define BC_GL_MATRIX(shader, mat) \ - glUniformMatrix3fv(glGetUniformLocation(shader, #mat), 1, 0, YUV::mat) + glUniformMatrix3fv(glGetUniformLocation(shader, #mat), 1, 1, YUV::mat) #define BC_GL_VECTOR(shader, vec) \ glUniform3fv(glGetUniformLocation(shader, #vec), 1, YUV::vec) diff --git a/cinelerra-5.1/cinelerra/record.C b/cinelerra-5.1/cinelerra/record.C index ece6d088..417063bd 100644 --- a/cinelerra-5.1/cinelerra/record.C +++ b/cinelerra-5.1/cinelerra/record.C @@ -702,8 +702,7 @@ const char* Record::current_mode() double Record::current_display_position() { -//printf("Record::current_display_position " -// _LD " " _LD "\n", total_samples, total_frames) +//printf("Record::current_display_position "%jd %jd\n", total_samples, total_frames); double result = -1.; Asset *asset = default_asset; if( writing_file ) { diff --git a/cinelerra-5.1/cinelerra/resample.C b/cinelerra-5.1/cinelerra/resample.C index a09cbad9..9e51a994 100644 --- a/cinelerra-5.1/cinelerra/resample.C +++ b/cinelerra-5.1/cinelerra/resample.C @@ -126,10 +126,8 @@ void Resample::resample_chunk(Samples *input_buffer, int num_used; int i, j, k; double *input = input_buffer->get_data(); -//printf("Resample::resample_chunk %d in_len=" _LD " input_size=%d\n", -//__LINE__, -//in_len, -//input_size); +//printf("Resample::resample_chunk %d in_len=%jd input_size=%d\n", +// __LINE__, in_len, input_size); intratio = (fabs(resample_ratio - floor(.5 + resample_ratio)) < .0001); fcn = .90 / resample_ratio; @@ -273,10 +271,8 @@ int Resample::resample(Samples *output, int result = 0; -// printf("Resample::resample 1 output_position=" _LD " out_position=" _LD " out_len=" _LD "\n", -// output_position, -// out_position, -// out_len); +//printf("Resample::resample 1 output_position=%jd out_position=%jd out_len=%jd\n", +// output_position, out_position, out_len); // Changed position if(labs(this->output_position - out_position) > 0 || direction != this->direction) diff --git a/cinelerra-5.1/cinelerra/resourcethread.C b/cinelerra-5.1/cinelerra/resourcethread.C index 2e53c4da..70138be0 100644 --- a/cinelerra-5.1/cinelerra/resourcethread.C +++ b/cinelerra-5.1/cinelerra/resourcethread.C @@ -448,7 +448,7 @@ void ResourceThread::do_video(VResourceThreadItem *item) if(!temp_picon) { - temp_picon = new VFrame(source_w, source_h, source_cmodel, 0); + temp_picon = new VFrame(0, -1, source_w, source_h, source_cmodel, -1); } // Get temporary to copy cached frame to diff --git a/cinelerra-5.1/cinelerra/trackcanvas.C b/cinelerra-5.1/cinelerra/trackcanvas.C index 81537be2..e781c002 100644 --- a/cinelerra-5.1/cinelerra/trackcanvas.C +++ b/cinelerra-5.1/cinelerra/trackcanvas.C @@ -676,17 +676,11 @@ void TrackCanvas::test_timer() void TrackCanvas::draw_indexes(Indexable *indexable) { + IndexState *index_state = indexable->index_state; // Don't redraw raw samples - IndexState *index_state = 0; - index_state = indexable->index_state; - - if(index_state->index_zoom > mwindow->edl->local_session->zoom_sample) return; - - draw_resources(0, 1, indexable); - draw_overlays(); flash(0); } diff --git a/cinelerra-5.1/cinelerra/undostack.C b/cinelerra-5.1/cinelerra/undostack.C index 9216c2e1..acc6544f 100644 --- a/cinelerra-5.1/cinelerra/undostack.C +++ b/cinelerra-5.1/cinelerra/undostack.C @@ -506,7 +506,7 @@ void UndoStackItem::set_data(char *data) new_size, &this->data_size, 0); -//printf("UndoStackItem::set_data 2 " _LD "\n", timer.get_difference()); +//printf("UndoStackItem::set_data 2 %jd\n", timer.get_difference()); // Testing // FILE *test1 = fopen("/tmp/undo1", "w"); diff --git a/cinelerra-5.1/ffmpeg/audio/h264.mp4 b/cinelerra-5.1/ffmpeg/audio/h264.mp4 new file mode 100644 index 00000000..7a2d70ea --- /dev/null +++ b/cinelerra-5.1/ffmpeg/audio/h264.mp4 @@ -0,0 +1 @@ +mp4 libfdk_aac diff --git a/cinelerra-5.1/ffmpeg/audio/mp4.dfl b/cinelerra-5.1/ffmpeg/audio/mp4.dfl index ca4ccd77..2a9f3437 100644 --- a/cinelerra-5.1/ffmpeg/audio/mp4.dfl +++ b/cinelerra-5.1/ffmpeg/audio/mp4.dfl @@ -1 +1 @@ -h265.mp4 +h264.mp4 diff --git a/cinelerra-5.1/ffmpeg/audio/passes1and2_h264.mp4 b/cinelerra-5.1/ffmpeg/audio/passes1and2_h264.mp4 new file mode 100644 index 00000000..ab6b0cc5 --- /dev/null +++ b/cinelerra-5.1/ffmpeg/audio/passes1and2_h264.mp4 @@ -0,0 +1,2 @@ +fmp4 libfdk_aac +b=128k diff --git a/cinelerra-5.1/ffmpeg/audio/passes1and2_h265.mp4 b/cinelerra-5.1/ffmpeg/audio/passes1and2_h265.mp4 new file mode 100644 index 00000000..ab6b0cc5 --- /dev/null +++ b/cinelerra-5.1/ffmpeg/audio/passes1and2_h265.mp4 @@ -0,0 +1,2 @@ +fmp4 libfdk_aac +b=128k diff --git a/cinelerra-5.1/ffmpeg/video/pass1of2_h264.mp4 b/cinelerra-5.1/ffmpeg/video/pass1of2_h264.mp4 new file mode 100644 index 00000000..85f8f8f4 --- /dev/null +++ b/cinelerra-5.1/ffmpeg/video/pass1of2_h264.mp4 @@ -0,0 +1,8 @@ +mp4 libx264 +# pass 1 of 2, you must render the 2nd pass using pass2of2... +flags +pass1 +passlogfile /tmp/2passes_h264.log +b=2600k +# use framerate for 1 keyframe/sec, needed for seeks +keyint_min=25 +x264opts keyint=25 diff --git a/cinelerra-5.1/ffmpeg/video/pass1of2_h265.mp4 b/cinelerra-5.1/ffmpeg/video/pass1of2_h265.mp4 new file mode 100644 index 00000000..ba0d4a21 --- /dev/null +++ b/cinelerra-5.1/ffmpeg/video/pass1of2_h265.mp4 @@ -0,0 +1,7 @@ +mp4 libx265 +# Pass 1 of 2, you must next render using pass2of2... +cin_quality=-1 +b=2600k +# use framerate for 1 keyframe/sec, needed for seeks +keyint_min=30 +x265-params=keyint=30:pass=1:stats=/tmp/2passes_h265.log diff --git a/cinelerra-5.1/ffmpeg/video/pass2of2_h264.mp4 b/cinelerra-5.1/ffmpeg/video/pass2of2_h264.mp4 new file mode 100644 index 00000000..25c7dd19 --- /dev/null +++ b/cinelerra-5.1/ffmpeg/video/pass2of2_h264.mp4 @@ -0,0 +1,8 @@ +mp4 libx264 +# 2nd pass, you must render first with pass1of2... +flags +pass2 +passlogfile /tmp/2passes_h264.log +b=2600k +# use framerate for 1 keyframe/sec, needed for seeks +keyint_min=25 +x264opts keyint=25 diff --git a/cinelerra-5.1/ffmpeg/video/pass2of2_h265.mp4 b/cinelerra-5.1/ffmpeg/video/pass2of2_h265.mp4 new file mode 100644 index 00000000..131865dd --- /dev/null +++ b/cinelerra-5.1/ffmpeg/video/pass2of2_h265.mp4 @@ -0,0 +1,7 @@ +mp4 libx265 +# Pass 2 of 2, you must first render using pass1of2... +cin_quality=-1 +b=2600k +# use framerate for 1 keyframe/sec, needed for seeks +keyint_min=30 +x265-params=keyint=30:pass=2:stats=/tmp/2passes_h265.log diff --git a/cinelerra-5.1/guicast/bccolors.C b/cinelerra-5.1/guicast/bccolors.C index 5d181696..e587321d 100644 --- a/cinelerra-5.1/guicast/bccolors.C +++ b/cinelerra-5.1/guicast/bccolors.C @@ -128,7 +128,7 @@ int HSV::hsv_to_yuv(int &y, int &u, int &v, float h, float s, float va, int max) YUV YUV::yuv; float YUV::yuv_to_rgb_matrix[9]; float YUV::rgb_to_yuv_matrix[9]; -float YUV::rgb_to_y_vector[3]; +float *const YUV::rgb_to_y_vector = YUV::rgb_to_yuv_matrix; YUV::YUV() { @@ -225,28 +225,24 @@ void YUV::init(double Kr, double Kb, int mpeg) vtor16f, vtog16f, utog16f, utob16f); rgb_to_yuv_matrix[0] = r_to_y; - rgb_to_yuv_matrix[1] = r_to_u; - rgb_to_yuv_matrix[2] = r_to_v; - rgb_to_yuv_matrix[3] = g_to_y; + rgb_to_yuv_matrix[1] = g_to_y; + rgb_to_yuv_matrix[2] = b_to_y; + rgb_to_yuv_matrix[3] = r_to_u; rgb_to_yuv_matrix[4] = g_to_u; - rgb_to_yuv_matrix[5] = g_to_v; - rgb_to_yuv_matrix[6] = b_to_y; - rgb_to_yuv_matrix[7] = b_to_u; + rgb_to_yuv_matrix[5] = b_to_u; + rgb_to_yuv_matrix[6] = r_to_v; + rgb_to_yuv_matrix[7] = g_to_v; rgb_to_yuv_matrix[8] = b_to_v; - rgb_to_y_vector[0] = r_to_y; - rgb_to_y_vector[1] = g_to_y; - rgb_to_y_vector[2] = b_to_y; - float yscale = 1.f / yrangef; yuv_to_rgb_matrix[0] = yscale; - yuv_to_rgb_matrix[1] = yscale; - yuv_to_rgb_matrix[2] = yscale; - yuv_to_rgb_matrix[3] = 0; + yuv_to_rgb_matrix[1] = 0; + yuv_to_rgb_matrix[2] = v_to_r; + yuv_to_rgb_matrix[3] = yscale; yuv_to_rgb_matrix[4] = u_to_g; - yuv_to_rgb_matrix[5] = u_to_b; - yuv_to_rgb_matrix[6] = v_to_r; - yuv_to_rgb_matrix[7] = v_to_g; + yuv_to_rgb_matrix[5] = v_to_g; + yuv_to_rgb_matrix[6] = yscale; + yuv_to_rgb_matrix[7] = u_to_b; yuv_to_rgb_matrix[8] = 0; } diff --git a/cinelerra-5.1/guicast/bccolors.h b/cinelerra-5.1/guicast/bccolors.h index 86877352..9226f3a5 100644 --- a/cinelerra-5.1/guicast/bccolors.h +++ b/cinelerra-5.1/guicast/bccolors.h @@ -188,7 +188,7 @@ public: static YUV yuv; static float yuv_to_rgb_matrix[9]; static float rgb_to_yuv_matrix[9]; - static float rgb_to_y_vector[3]; + static float *const rgb_to_y_vector; inline float get_yminf() { return yminf; } #define YUV_rgb_to_yuv_8(r,g,b, y,u,v) \ diff --git a/cinelerra-5.1/guicast/vframe.C b/cinelerra-5.1/guicast/vframe.C index e8dad7ea..79904192 100644 --- a/cinelerra-5.1/guicast/vframe.C +++ b/cinelerra-5.1/guicast/vframe.C @@ -280,7 +280,8 @@ int VFrame::reset_parameters(int do_opengl) timestamp = -1.; is_keyframe = 0; draw_point = 0; - set_pixel_color(BLACK); + pixel_rgb = 0x000000; // BLACK + pixel_yuv = 0x008080; stipple = 0; if(do_opengl) diff --git a/cinelerra-5.1/info/plugins.txt b/cinelerra-5.1/info/plugins.txt index 3318eaf4..b8e9253e 100644 --- a/cinelerra-5.1/info/plugins.txt +++ b/cinelerra-5.1/info/plugins.txt @@ -91,6 +91,7 @@ Gamma: Converts the logarithmic colors to linear colors using gamma and maximum value. Gradient: Overlays a smooth color gradient on top of every video frame. +HistEq: Remap colors using blended histogram weights. Histogram: Shows the number of occurrences of each color on a histogram plot. Histogram Bezier: Uses a Bezier curve (parametric) on the histogram plot. diff --git a/cinelerra-5.1/picon/cinfinity/histeq.png b/cinelerra-5.1/picon/cinfinity/histeq.png new file mode 100644 index 00000000..658d2f38 Binary files /dev/null and b/cinelerra-5.1/picon/cinfinity/histeq.png differ diff --git a/cinelerra-5.1/plugin_defs b/cinelerra-5.1/plugin_defs index 39a72d7d..2d4690ea 100644 --- a/cinelerra-5.1/plugin_defs +++ b/cinelerra-5.1/plugin_defs @@ -20,7 +20,7 @@ transforms := 1080to480 1080to540 720to480 lens perspective photoscale \ plugin_dirs += colors colors := brightness bluebanana C41 color3way colorbalance huesaturation \ - gamma gradient histogram histogram_bezier threshold + gamma gradient histeq histogram histogram_bezier threshold plugin_dirs += exotic exotic := aging burn dot holo oil edge spherecam diff --git a/cinelerra-5.1/plugins/Makefile b/cinelerra-5.1/plugins/Makefile index bf9b8367..a492ca86 100644 --- a/cinelerra-5.1/plugins/Makefile +++ b/cinelerra-5.1/plugins/Makefile @@ -67,6 +67,7 @@ DIRS = $(OPENCV_OBJS) \ gamma \ gradient \ graphic \ + histeq \ histogram \ histogram_bezier \ holo \ diff --git a/cinelerra-5.1/plugins/histeq/.gdb_history b/cinelerra-5.1/plugins/histeq/.gdb_history new file mode 100644 index 00000000..ee24cbc7 --- /dev/null +++ b/cinelerra-5.1/plugins/histeq/.gdb_history @@ -0,0 +1,23 @@ +p /x 0xff*3 +p /x 0xff*3 * 0x55 +p /x 0xff*3 * 0x57 +p /x 0xff*3 * 0x56 +p /x 0x5555*3 +p /x 0xff*3 * 0x5555 +p /x 0xff*3 * 0x5555 /257 +p /x 0xff*3 * 0x5555 /256 +p /x 0xff*3 * 0x5555 /254 +p /x 0xff*3 * 0x5555 /253 +p /x 0xff*3 * 0x5555 /254 +p /x 0xff*3 * 0x5555 /255 +p (766*0x5555)/255 +p /x (766*0x5555)/255 +p /x (0x2fd*0x5555)/255 +0xffff/0x5555 +p (double)0xffff/0x5555 +r +y +r +y +r +q diff --git a/cinelerra-5.1/plugins/histeq/Makefile b/cinelerra-5.1/plugins/histeq/Makefile new file mode 100644 index 00000000..a30b3279 --- /dev/null +++ b/cinelerra-5.1/plugins/histeq/Makefile @@ -0,0 +1,10 @@ +include ../../plugin_defs + +OBJS = \ + $(OBJDIR)/histeq.o \ + +PLUGIN = histeq + +include ../../plugin_config + +$(OBJDIR)/histeq.o: histeq.C diff --git a/cinelerra-5.1/plugins/histeq/histeq.C b/cinelerra-5.1/plugins/histeq/histeq.C new file mode 100644 index 00000000..a4f647cd --- /dev/null +++ b/cinelerra-5.1/plugins/histeq/histeq.C @@ -0,0 +1,696 @@ + +/* + * CINELERRA + * Copyright (C) 2008-2012 Adam Williams + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include +#include +#include +#include + +#include "histeq.h" +#include "filexml.h" +#include "language.h" +#include "loadbalance.h" +#include "bccolors.h" +#include "vframe.h" + +class HistEqMain; +class HistEqEngine; +class HistEqWindow; + +REGISTER_PLUGIN(HistEqMain) + +HistEqConfig::HistEqConfig() +{ + split = 0; + plot = 0; + blend = 0.5; + gain = 1.0; +} + +HistEqConfig::~HistEqConfig() +{ +} + +void HistEqConfig::copy_from(HistEqConfig &that) +{ + split = that.split; + plot = that.plot; + blend = that.blend; + gain = that.gain; +} + +int HistEqConfig::equivalent(HistEqConfig &that) +{ + return 1; +} + +void HistEqConfig::interpolate(HistEqConfig &prev, HistEqConfig &next, + int64_t prev_frame, int64_t next_frame, int64_t current_frame) +{ + copy_from(prev); +} + + +HistEqWindow::HistEqWindow(HistEqMain *plugin) + : PluginClientWindow(plugin, plugin->w, plugin->h, plugin->w, plugin->h, 0) +{ + this->plugin = plugin; +} + +HistEqWindow::~HistEqWindow() +{ +} + + +void HistEqWindow::create_objects() +{ + int x = 10, y = 10; + int cw = get_w()-2*x, ch = cw*3/4; + add_subwindow(canvas = new HistEqCanvas(this, plugin, x, y, cw, ch)); + y += canvas->get_h() + 10; + + add_subwindow(split = new HistEqSplit(this, plugin, x, y)); + y += split->get_h() + 10; + + add_subwindow(plot = new HistEqPlot(this, plugin, x, y)); + y += plot->get_h() + 10; + + int x1 = x + 60; + add_subwindow(new BC_Title(x, y, _("Blend:"))); + add_subwindow(blend = new HistEqBlend(this, plugin, x1, y)); + y += blend->get_h() + 10; + + add_subwindow(new BC_Title(x, y, _("Gain:"))); + add_subwindow(gain = new HistEqGain(this, plugin, x1, y)); + y += gain->get_h() + 10; + + show_window(); +} + +void HistEqWindow::update() +{ +} + +HistEqCanvas::HistEqCanvas(HistEqWindow *gui, HistEqMain *plugin, + int x, int y, int w, int h) + : BC_SubWindow(x, y, w, h, BLACK) +{ + this->gui = gui; + this->plugin = plugin; +} +void HistEqCanvas::clear() +{ + clear_box(0,0, get_w(),get_h()); +} + +void HistEqCanvas::draw_bins(HistEqMain *plugin) +{ + set_color(GREEN); + int *data = plugin->bins; + int n = plugin->binsz, max = 0; + for( int i=0; i mx ) mx = m; + } + double lmx = mx>0 ? log(mx) : 0; + int y1 = ch * (1 - lmx/lmax); + draw_line(x,0, x,y1); + x0 = x1; + } +} + +void HistEqCanvas::draw_wts(HistEqMain *plugin) +{ + float *wts = plugin->wts; + int n = plugin->binsz; + set_color(BLUE); + int cw1 = get_w()-1, ch1 = get_h()-1; + float g0 = plugin->config.gain, g1 = 1-g0; + int x1 = 0, y1 = ch1; + while( x1 < cw1 ) { + int x0 = x1++, y0 = y1; + int is = (n * x1) / cw1; + float fy = wts[is]*g0 + ((float)x1/cw1)*g1; + y1 = (1-fy) * ch1; + draw_line(x0,y0, x1,y1); + } +} + +void HistEqCanvas::draw_reg(HistEqMain *plugin) +{ + set_color(WHITE); + int cw1 = get_w()-1, ch1 = get_h()-1; + float g0 = plugin->config.gain, g1 = 1-g0; + int x0 = 0, x1 = plugin->binsz-1; + double a = plugin->a, b = plugin->b; + float fy0 = (a*x0 + b)*g0 + 0*g1; + float fy1 = (a*x1 + b)*g0 + 1*g1; + int y0 = (1 - fy0) * ch1; + int y1 = (1 - fy1) * ch1; + draw_line(0,y0, cw1,y1); +} + +void HistEqCanvas::draw_lut(HistEqMain *plugin) +{ + int *lut = plugin->lut; + int n = plugin->lutsz-1; + double s = 1. / n; + set_color(RED); + int cw1 = get_w()-1, ch1 = get_h()-1; + int x1 = 0, y1 = ch1; + while( x1 < cw1 ) { + int x0 = x1++, y0 = y1; + int is = (n * x1) / cw1; + y1 = (1-s*lut[is]) * ch1; + draw_line(x0,y0, x1,y1); + } +} + +void HistEqCanvas::update(HistEqMain *plugin) +{ + clear(); + draw_bins(plugin); + draw_wts(plugin); + draw_reg(plugin); + draw_lut(plugin); + flash(); +} + +HistEqSplit::HistEqSplit(HistEqWindow *gui, HistEqMain *plugin, int x, int y) + : BC_CheckBox(x, y, plugin->config.split, _("Split output")) +{ + this->gui = gui; + this->plugin = plugin; +} +HistEqSplit::~HistEqSplit() +{ +} + +int HistEqSplit::handle_event() +{ + plugin->config.split = get_value(); + plugin->send_configure_change(); + return 1; +} + +HistEqPlot::HistEqPlot(HistEqWindow *gui, HistEqMain *plugin, int x, int y) + : BC_CheckBox(x, y, plugin->config.plot, _("Plot bins/lut")) +{ + this->gui = gui; + this->plugin = plugin; +} +HistEqPlot::~HistEqPlot() +{ +} + +int HistEqPlot::handle_event() +{ + plugin->config.plot = get_value(); + plugin->send_configure_change(); + return 1; +} + +HistEqBlend::HistEqBlend(HistEqWindow *gui, HistEqMain *plugin, int x, int y) + : BC_FSlider(x, y, 0, 150, 200, 0, 1.0, plugin->config.blend, 0) +{ + this->gui = gui; + this->plugin = plugin; + set_precision(0.01); +} +HistEqBlend::~HistEqBlend() +{ +} + +int HistEqBlend::handle_event() +{ + plugin->config.blend = get_value(); + plugin->send_configure_change(); + return 1; +} + + +HistEqGain::HistEqGain(HistEqWindow *gui, HistEqMain *plugin, int x, int y) + : BC_FSlider(x, y, 0, 150, 200, 0, 1.0, plugin->config.gain, 0) +{ + this->gui = gui; + this->plugin = plugin; + set_precision(0.01); +} +HistEqGain::~HistEqGain() +{ +} + +int HistEqGain::handle_event() +{ + plugin->config.gain = get_value(); + plugin->send_configure_change(); + return 1; +} + + +HistEqMain::HistEqMain(PluginServer *server) + : PluginVClient(server) +{ + w = 300; h = 375; + engine = 0; + sz = 0; + binsz = bsz = 0; bins = 0; + lutsz = lsz = 0; lut = 0; + wsz = 0; wts = 0; + a = 0; b = 0; +} + +HistEqMain::~HistEqMain() +{ + delete engine; + delete [] bins; + delete [] lut; + delete [] wts; +} + +const char* HistEqMain::plugin_title() { return _("HistEq"); } +int HistEqMain::is_realtime() { return 1; } + + +NEW_WINDOW_MACRO(HistEqMain, HistEqWindow) + +LOAD_CONFIGURATION_MACRO(HistEqMain, HistEqConfig) + +void HistEqMain::update_gui() +{ + if( !thread ) return; + if( !load_configuration() ) return; + ((HistEqWindow*)thread->window)->lock_window("HistEqMain::update_gui"); + HistEqWindow* gui = (HistEqWindow*)thread->window; + gui->update(); + gui->unlock_window(); +} + +void HistEqMain::save_data(KeyFrame *keyframe) +{ + FileXML output; + output.set_shared_output(keyframe->get_data(), MESSAGESIZE); + output.tag.set_title("HISTEQ"); + output.tag.set_property("W", w); + output.tag.set_property("H", h); + output.tag.set_property("SPLIT", config.split); + output.tag.set_property("PLOT", config.plot); + output.tag.set_property("BLEND", config.blend); + output.tag.set_property("GAIN", config.gain); + output.append_tag(); + output.tag.set_title("/HISTEQ"); + output.append_tag(); + output.append_newline(); + output.terminate_string(); +} + +void HistEqMain::read_data(KeyFrame *keyframe) +{ + FileXML input; + input.set_shared_input(keyframe->get_data(), strlen(keyframe->get_data())); + int result = 0; + while( !(result=input.read_tag()) ) { + if( input.tag.title_is("HISTEQ") ) { + if(is_defaults()) { + w = input.tag.get_property("W", w); + h = input.tag.get_property("H", h); + } + config.split = input.tag.get_property("SPLIT", config.split); + config.plot = input.tag.get_property("PLOT", config.plot); + config.blend = input.tag.get_property("BLEND", config.blend); + config.gain = input.tag.get_property("GAIN", config.gain); + } + } +} + +void HistEqMain::render_gui(void *data) +{ + if( !thread ) return; + ((HistEqWindow*)thread->window)->lock_window("HistEqMain::render_gui 1"); + HistEqWindow *gui = (HistEqWindow*)thread->window; + gui->canvas->update((HistEqMain *)data); + gui->unlock_window(); +} + +// regression line +static void fit(float *dat, int n, double &a, double &b) +{ + double sy = 0; + for( int i=0; iinput = this->output = frame; + + int colormodel = frame->get_color_model(); + lutsz = 0x10000; + binsz = (3*0xffff) + 1; + switch( colormodel ) { + case BC_RGB888: + case BC_RGBA8888: + binsz = (3*0xff) + 1; + lutsz = 0x100; + break; + case BC_RGB_FLOAT: + case BC_RGBA_FLOAT: + binsz = (3*0x5555) + 1; + break; + } + if( binsz != bsz ) { delete bins; bins = 0; bsz = 0; } + if( !bins ) bins = new int[bsz = binsz]; + if( binsz+1 != wsz ) { delete wts; wts = 0; wsz = 0; } + if( !wts ) wts = new float[wsz = binsz+1]; + if( lutsz != lsz ) { delete lut; lut = 0; lsz = 0; } + if( !lut ) lut = new int[lsz = lutsz]; + + if(!engine) engine = new HistEqEngine(this, + get_project_smp() + 1, get_project_smp() + 1); + engine->process_packages(HistEqEngine::HISTEQ, frame); + +// sum the results, not all clients may have run + memset(bins, 0, binsz*sizeof(bins[0])); + for( int i=0, n=engine->get_total_clients(); iget_client(i); + if( !unit->valid ) continue; + for( int i=0; ibins[i]; + } + +// Remove top and bottom from calculations. +// Doesn't work in high precision colormodels. + int n = frame->get_w() * frame->get_h(); + int binsz1 = binsz-1, lutsz1 = lutsz-1; + n -= bins[0]; bins[0] = 0; + n -= bins[binsz1]; bins[binsz1] = 0; + sz = n; + +// integrate and normalize + for( int i=0,t=0; i mn && wts[mx-1] > fmx ) --mx; + n = mx-mn+1; fit(&wts[mn], n, a, b); +// home y intercept + b -= a * mn; + if( (a*n + b) < 1 ) a = (1 - b) / n; + if( b > 0 ) { a = (a*n + b) / n; b = 0; } + double blend = config.blend, blend1 = 1-blend; + double r = (double)binsz1 / lutsz1; + float g0 = config.gain, g1 = 1-g0; + for( int i=0; iprocess_packages(HistEqEngine::APPLY, frame); + return 0; +} + +HistEqPackage::HistEqPackage() + : LoadPackage() +{ +} + +HistEqUnit::HistEqUnit(HistEqEngine *server, HistEqMain *plugin) + : LoadClient(server) +{ + this->plugin = plugin; + this->server = server; + bins = 0; + binsz = 0; + valid = 0; +} + +HistEqUnit::~HistEqUnit() +{ + delete [] bins; +} + +void HistEqUnit::process_package(LoadPackage *package) +{ + if( binsz != plugin->binsz ) { + delete bins; bins = 0; binsz = 0; + } + if( !bins ) { + bins = new int[binsz = plugin->binsz]; + } + if( !valid ) { + valid = 1; + bzero(bins, binsz*sizeof(bins[0])); + } + + HistEqPackage *pkg = (HistEqPackage*)package; + switch( server->operation ) { + case HistEqEngine::HISTEQ: { + +#define HISTEQ_HEAD(type) { \ + type **rows = (type**)data->get_rows(); \ + for( int iy=pkg->y0; iyy1; ++iy ) { \ + type *row = rows[iy]; \ + for( int ix=0; ixdata; + int colormodel = data->get_color_model(); + int w = data->get_w(), comps = BC_CModels::components(colormodel); + + switch( colormodel ) { + case BC_RGB888: + case BC_RGBA8888: + HISTEQ_HEAD(unsigned char) + int r = row[0], g = row[1], b = row[2]; + int i = r + g + b; + HISTEQ_TAIL(comps) + break; + case BC_RGB161616: + case BC_RGBA16161616: + HISTEQ_HEAD(uint16_t) + int r = row[0], g = row[1], b = row[2]; + int i = r + g + b; + HISTEQ_TAIL(comps) + break; + case BC_RGB_FLOAT: + case BC_RGBA_FLOAT: + HISTEQ_HEAD(float) + int r = (int)(row[0] * 0x5555); + int g = (int)(row[1] * 0x5555); + int b = (int)(row[2] * 0x5555); + int i = r + g + b; bclamp(i, 0,0xffff); + HISTEQ_TAIL(comps) + break; + case BC_YUV888: + case BC_YUVA8888: + HISTEQ_HEAD(unsigned char) + int y = (row[0]<<8) + row[0]; + int u = (row[1]<<8) + row[1]; + int v = (row[2]<<8) + row[2]; + int r, g, b; + YUV::yuv.yuv_to_rgb_16(r, g, b, y, u, v); + int i = r + g + b; + HISTEQ_TAIL(comps) + break; + case BC_YUV161616: + case BC_YUVA16161616: + HISTEQ_HEAD(uint16_t) + int r, g, b; + YUV::yuv.yuv_to_rgb_16(r, g, b, row[0], row[1], row[2]); + int i = r + g + b; + HISTEQ_TAIL(comps) + break; + } + break; } + case HistEqEngine::APPLY: { +#define PROCESS_RGB(type, components, max) { \ + type **rows = (type**)input->get_rows(); \ + for( int iy=pkg->y0; iyy1; ++iy ) { \ + type *row = rows[iy]; \ + int x1 = !split ? w : (iy * w) / h; \ + for( int x=0; xget_rows(); \ + for( int iy=pkg->y0; iyy1; ++iy ) { \ + type *row = rows[iy]; \ + int x1 = !split ? w : (iy * w) / h; \ + for( int ix=0; ix> 8; \ + row[1] = u >> 8; \ + row[2] = v >> 8; \ + } \ + else { \ + row[0] = y; row[1] = u; row[2] = v; \ + } \ + row += components; \ + } \ + } \ +} +#define PROCESS_FLOAT(components) { \ + float **rows = (float**)input->get_rows(); \ + for( int iy=pkg->y0; iyy1; ++iy ) { \ + float *row = rows[iy]; \ + int x1 = !split ? w : (iy * w) / h; \ + for( int ix=0; ixinput; + int w = input->get_w(), h = input->get_h(); + int split = plugin->config.split; + int *lut = plugin->lut; + + switch(input->get_color_model()) { + case BC_RGB888: + PROCESS_RGB(unsigned char, 3, 0xff) + break; + case BC_RGBA8888: + PROCESS_RGB(unsigned char, 4, 0xff) + break; + case BC_RGB161616: + PROCESS_RGB(uint16_t, 3, 0xffff) + break; + case BC_RGBA16161616: + PROCESS_RGB(uint16_t, 4, 0xffff) + break; + case BC_RGB_FLOAT: + PROCESS_FLOAT(3); + break; + case BC_RGBA_FLOAT: + PROCESS_FLOAT(4); + break; + case BC_YUV888: + PROCESS_YUV(unsigned char, 3, 0xff) + break; + case BC_YUVA8888: + PROCESS_YUV(unsigned char, 4, 0xff) + break; + case BC_YUV161616: + PROCESS_YUV(uint16_t, 3, 0xffff) + break; + case BC_YUVA16161616: + PROCESS_YUV(uint16_t, 4, 0xffff) + break; + } + break; } + } +} + +HistEqEngine::HistEqEngine(HistEqMain *plugin, + int total_clients, + int total_packages) + : LoadServer(total_clients, total_packages) +{ + this->plugin = plugin; +} + +void HistEqEngine::init_packages() +{ + int h = data->get_h(); + int y0 = 0; + + for( int i=0, n=get_total_packages(); iy0 = y0; pkg->y1 = y1; + y0 = y1; + } + for( int i=0, n=get_total_clients(); ivalid = 0; // set if unit runs + } +} + +LoadClient* HistEqEngine::new_client() +{ + return new HistEqUnit(this, plugin); +} + +LoadPackage* HistEqEngine::new_package() +{ + return new HistEqPackage; +} + +void HistEqEngine::process_packages(int operation, VFrame *data) +{ + this->data = data; + this->operation = operation; + + LoadServer::process_packages(); +} + + diff --git a/cinelerra-5.1/plugins/histeq/histeq.h b/cinelerra-5.1/plugins/histeq/histeq.h new file mode 100644 index 00000000..f8da0169 --- /dev/null +++ b/cinelerra-5.1/plugins/histeq/histeq.h @@ -0,0 +1,184 @@ + +/* + * CINELERRA + * Copyright (C) 1997-2011 Adam Williams + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef HISTOGRAM_H +#define HISTOGRAM_H + + +#include "histeq.inc" +#include "loadbalance.h" +#include "bccolors.h" +#include "pluginvclient.h" + +class HistEqConfig { +public: + HistEqConfig(); + ~HistEqConfig(); + + int split; + int plot; + float blend; + float gain; + + void copy_from(HistEqConfig &that); + int equivalent(HistEqConfig &that); + void interpolate(HistEqConfig &prev, HistEqConfig &next, + int64_t prev_frame, int64_t next_frame, int64_t current_frame); +}; + +class HistEqSplit : public BC_CheckBox +{ +public: + HistEqSplit(HistEqWindow *gui, HistEqMain *plugin, int x, int y); + ~HistEqSplit(); + int handle_event(); + + HistEqWindow *gui; + HistEqMain *plugin; +}; + +class HistEqPlot : public BC_CheckBox +{ +public: + HistEqPlot(HistEqWindow *gui, HistEqMain *plugin, int x, int y); + ~HistEqPlot(); + int handle_event(); + + HistEqWindow *gui; + HistEqMain *plugin; +}; + +class HistEqBlend : public BC_FSlider +{ +public: + HistEqBlend(HistEqWindow *gui, HistEqMain *plugin, int x, int y); + ~HistEqBlend(); + int handle_event(); + + HistEqWindow *gui; + HistEqMain *plugin; +}; + +class HistEqGain : public BC_FSlider +{ +public: + HistEqGain(HistEqWindow *gui, HistEqMain *plugin, int x, int y); + ~HistEqGain(); + int handle_event(); + + HistEqWindow *gui; + HistEqMain *plugin; +}; + +class HistEqCanvas : public BC_SubWindow +{ +public: + HistEqCanvas(HistEqWindow *gui, HistEqMain *plugin, + int x, int y, int w, int h); + void clear(); + void draw_bins(HistEqMain *plugin); + void draw_wts(HistEqMain *plugin); + void draw_reg(HistEqMain *plugin); + void draw_lut(HistEqMain *plugin); + void update(HistEqMain *plugin); + + HistEqMain *plugin; + HistEqWindow *gui; +}; + +class HistEqWindow : public PluginClientWindow +{ +public: + HistEqWindow(HistEqMain *plugin); + ~HistEqWindow(); + + HistEqMain *plugin; + HistEqSplit *split; + HistEqPlot *plot; + HistEqBlend *blend; + HistEqGain *gain; + HistEqCanvas *canvas; + + void create_objects(); + void update(); +}; + +class HistEqMain : public PluginVClient +{ +public: + HistEqMain(PluginServer *server); + ~HistEqMain(); + + int process_buffer(VFrame *frame, int64_t start_position, double frame_rate); + int is_realtime(); + void save_data(KeyFrame *keyframe); + void read_data(KeyFrame *keyframe); + void update_gui(); + + void render_gui(void *data); + + PLUGIN_CLASS_MEMBERS(HistEqConfig) + + VFrame *input, *output; + HistEqEngine *engine; + int w, h; + int sz; + double a, b; + int binsz, bsz, *bins; + int lutsz, lsz, *lut; + int wsz; float *wts; +}; + +class HistEqPackage : public LoadPackage +{ +public: + HistEqPackage(); + int y0, y1; +}; + +class HistEqUnit : public LoadClient +{ +public: + HistEqUnit(HistEqEngine *server, HistEqMain *plugin); + ~HistEqUnit(); + void process_package(LoadPackage *package); + HistEqEngine *server; + HistEqMain *plugin; + int valid; + int binsz, *bins; +}; + +class HistEqEngine : public LoadServer +{ +public: + HistEqEngine(HistEqMain *plugin, int total_clients, int total_packages); + void process_packages(int operation, VFrame *data); + void init_packages(); + LoadClient* new_client(); + LoadPackage* new_package(); + HistEqMain *plugin; + int operation; + + enum { HISTEQ, APPLY }; + VFrame *data; +}; + +#endif diff --git a/cinelerra-5.1/plugins/histeq/histeq.inc b/cinelerra-5.1/plugins/histeq/histeq.inc new file mode 100644 index 00000000..ae7ae3c3 --- /dev/null +++ b/cinelerra-5.1/plugins/histeq/histeq.inc @@ -0,0 +1,14 @@ +#ifndef __HISTEQ_H__ +#define __HISTEQ_H__ + +class HistEqConfig; +class HistEqSplit; +class HistEqBlend; +class HistEqGain; +class HistEqWindow; +class HistEqMain; +class HistEqPackage; +class HistEqUnit; +class HistEqEngine; + +#endif diff --git a/cinelerra-5.1/plugins/histogram/histogram.C b/cinelerra-5.1/plugins/histogram/histogram.C index 996edac9..183d5c0e 100644 --- a/cinelerra-5.1/plugins/histogram/histogram.C +++ b/cinelerra-5.1/plugins/histogram/histogram.C @@ -677,9 +677,6 @@ int HistogramMain::handle_opengl() if(!strcmp(get_output()->get_prev_effect(0), _("Color Balance"))) aggregate_colorbalance = 1; - if( BC_CModels::is_yuv(get_output()->get_color_model()) ) - shader_stack[current_shader++] = bc_gl_colors; - // The order of processing is fixed by this sequence if(aggregate_interpolation) INTERPOLATE_COMPILE(shader_stack, current_shader);