[Bf-blender-cvs] [39eb314] master: UI: Refactor timecode functions into BLI_timecode

Campbell Barton noreply at git.blender.org
Wed Jan 29 10:44:35 CET 2014


Commit: 39eb314cb922b805e9126d5f0352f31c2f84f151
Author: Campbell Barton
Date:   Wed Jan 29 20:01:30 2014 +1100
https://developer.blender.org/rB39eb314cb922b805e9126d5f0352f31c2f84f151

UI: Refactor timecode functions into BLI_timecode

- deduplicate timecode_simple_string from image.c
- replace V2D_UNIT_SECONDSSEQ with V2D_UNIT_SECONDS
- avoid possible buffer overflow bugs (sprintf -> BLI_snprintf)
- remove option not to use timecode and split into 2 functions

Patch D227 by Andrew Buttery with own refactoring.

===================================================================

M	source/blender/blenkernel/intern/image.c
A	source/blender/blenlib/BLI_timecode.h
M	source/blender/blenlib/CMakeLists.txt
A	source/blender/blenlib/intern/timecode.c
M	source/blender/editors/animation/anim_draw.c
M	source/blender/editors/include/ED_anim_api.h
M	source/blender/editors/include/UI_view2d.h
M	source/blender/editors/interface/view2d.c
M	source/blender/editors/space_sequencer/sequencer_draw.c

===================================================================

diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c
index 336656e..3e93ab0 100644
--- a/source/blender/blenkernel/intern/image.c
+++ b/source/blender/blenkernel/intern/image.c
@@ -68,6 +68,7 @@
 
 #include "BLI_blenlib.h"
 #include "BLI_threads.h"
+#include "BLI_timecode.h"  /* for stamp timecode format */
 #include "BLI_utildefines.h"
 
 #include "BKE_bmfont.h"
@@ -1520,30 +1521,6 @@ void BKE_imbuf_to_image_format(struct ImageFormatData *im_format, const ImBuf *i
 
 }
 
-static void timecode_simple_string(char *text, size_t text_size, const int cfra, int const frs_sec)
-{
-	int f = (int)(cfra % frs_sec);
-	int s = (int)(cfra / frs_sec);
-	int h = 0;
-	int m = 0;
-
-	if (s) {
-		m = (int)(s / 60);
-		s %= 60;
-
-		if (m) {
-			h = (int)(m / 60);
-			m %= 60;
-		}
-	}
-
-	if (frs_sec < 100) {
-		BLI_snprintf(text, text_size, "%02d:%02d:%02d.%02d", h, m, s, f);
-	}
-	else {
-		BLI_snprintf(text, text_size, "%02d:%02d:%02d.%03d", h, m, s, f);
-	}
-}
 
 #define STAMP_NAME_SIZE ((MAX_ID_NAME - 2) + 16)
 /* could allow access externally - 512 is for long names,
@@ -1607,8 +1584,9 @@ static void stampdata(Scene *scene, Object *camera, StampData *stamp_data, int d
 	}
 
 	if (scene->r.stamp & R_STAMP_TIME) {
-		timecode_simple_string(text, sizeof(text), scene->r.cfra, scene->r.frs_sec);
-		BLI_snprintf(stamp_data->time, sizeof(stamp_data->time), do_prefix ? "Time %s" : "%s", text);
+		const short timecode_style = USER_TIMECODE_SMPTE_FULL;
+		BLI_timecode_string_from_time(text, sizeof(text), 0, FRA2TIME(scene->r.cfra), FPS, timecode_style);
+		BLI_snprintf(stamp_data->time, sizeof(stamp_data->time), do_prefix ? "Timecode %s" : "%s", text);
 	}
 	else {
 		stamp_data->time[0] = '\0';
diff --git a/source/blender/blenlib/BLI_timecode.h b/source/blender/blenlib/BLI_timecode.h
new file mode 100644
index 0000000..b6cd011
--- /dev/null
+++ b/source/blender/blenlib/BLI_timecode.h
@@ -0,0 +1,41 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2008 Blender Foundation.
+ * All rights reserved.
+ *
+ * 
+ * Contributor(s): Joshua Leung
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef __BLI_TIMECODE_H__
+#define __BLI_TIMECODE_H__
+
+/** \file BLI_timecode.h
+ *  \ingroup BLI
+ */
+
+size_t BLI_timecode_string_from_time(
+        char *str, const size_t len, const int power, const float time_seconds,
+        const double scene_fps, const short timecode_style);
+
+size_t BLI_timecode_string_from_time_simple(
+        char *str, const size_t len, const int power, const float time_seconds);
+
+#endif  /* __BLI_TIMECODE_H__ */
diff --git a/source/blender/blenlib/CMakeLists.txt b/source/blender/blenlib/CMakeLists.txt
index 2a920a2..80e6292 100644
--- a/source/blender/blenlib/CMakeLists.txt
+++ b/source/blender/blenlib/CMakeLists.txt
@@ -98,6 +98,7 @@ set(SRC
 	intern/task.c
 	intern/threads.c
 	intern/time.c
+	intern/timecode.c
 	intern/uvproject.c
 	intern/voronoi.c
 	intern/voxel.c
@@ -166,6 +167,7 @@ set(SRC
 	BLI_sys_types.h
 	BLI_task.h
 	BLI_threads.h
+	BLI_timecode.h
 	BLI_utildefines.h
 	BLI_uvproject.h
 	BLI_vfontdata.h
diff --git a/source/blender/blenlib/intern/timecode.c b/source/blender/blenlib/intern/timecode.c
new file mode 100644
index 0000000..cd70374
--- /dev/null
+++ b/source/blender/blenlib/intern/timecode.c
@@ -0,0 +1,218 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2008 Blender Foundation.
+ * All rights reserved.
+ *
+ * 
+ * Contributor(s): Joshua Leung
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/blendlib/intern/timecode.c
+ *  \ingroup blendlib
+ *
+ * Time-Code string formatting
+ */
+
+#include <stdio.h>
+
+
+#include "BLI_string.h"
+#include "BLI_math.h"
+
+#include "BLI_timecode.h"  /* own include */
+
+#include "BLI_strict_flags.h"
+
+#include "DNA_userdef_types.h"  /* for eTimecodeStyles only */
+
+
+/**
+ * Generate timecode/frame number string and store in \a str
+ *
+ * \param str  destination string
+ * \param maxncpy  maximum number of characters to copy ``sizeof(str)``
+ * \param power  special setting for #View2D grid drawing,
+ *        used to specify how detailed we need to be
+ * \param time_seconds  time total time in seconds
+ * \param fps  frames per second, typically from the #FPS macro
+ * \param timecode_style  enum from eTimecodeStyles
+ * \return length of \a str
+ */
+
+size_t BLI_timecode_string_from_time(
+        char *str, const size_t maxncpy, const int power, const float time_seconds,
+        const double fps, const short timecode_style)
+{
+	int hours = 0, minutes = 0, seconds = 0, frames = 0;
+	float time = time_seconds;
+	char neg[2] = {'\0'};
+	size_t rlen;
+
+	/* get cframes */
+	if (time < 0) {
+		/* correction for negative cfraues */
+		neg[0] = '-';
+		time = -time;
+	}
+
+	if (time >= 3600) {
+		/* hours */
+		/* XXX should we only display a single digit for hours since clips are
+		 *     VERY UNLIKELY to be more than 1-2 hours max? However, that would
+		 *     go against conventions...
+		 */
+		hours = (int)time / 3600;
+		time = (float)fmod(time, 3600);
+	}
+
+	if (time >= 60) {
+		/* minutes */
+		minutes = (int)time / 60;
+		time = (float)fmod(time, 60);
+	}
+
+	if (power <= 0) {
+		/* seconds + frames
+		 * Frames are derived from 'fraction' of second. We need to perform some additional rounding
+		 * to cope with 'half' frames, etc., which should be fine in most cases
+		 */
+		seconds = (int)time;
+		frames = iroundf((float)(((double)time - (double)seconds) * fps));
+	}
+	else {
+		/* seconds (with pixel offset rounding) */
+		seconds = iroundf(time);
+	}
+
+	switch (timecode_style) {
+		case USER_TIMECODE_MINIMAL:
+		{
+			/* - In general, minutes and seconds should be shown, as most clips will be
+			 *   within this length. Hours will only be included if relevant.
+			 * - Only show frames when zoomed in enough for them to be relevant
+			 *   (using separator of '+' for frames).
+			 *   When showing frames, use slightly different display to avoid confusion with mm:ss format
+			 */
+			if (power <= 0) {
+				/* include "frames" in display */
+				if (hours) {
+					rlen = BLI_snprintf(str, maxncpy, "%s%02d:%02d:%02d+%02d", neg, hours, minutes, seconds, frames);
+				}
+				else if (minutes) {
+					rlen = BLI_snprintf(str, maxncpy, "%s%02d:%02d+%02d", neg, minutes, seconds, frames);
+				}
+				else {
+					rlen = BLI_snprintf(str, maxncpy, "%s%d+%02d", neg, seconds, frames);
+				}
+			}
+			else {
+				/* don't include 'frames' in display */
+				if (hours) {
+					rlen = BLI_snprintf(str, maxncpy, "%s%02d:%02d:%02d", neg, hours, minutes, seconds);
+				}
+				else {
+					rlen = BLI_snprintf(str, maxncpy, "%s%02d:%02d", neg, minutes, seconds);
+				}
+			}
+			break;
+		}
+		case USER_TIMECODE_SMPTE_MSF:
+		{
+			/* reduced SMPTE format that always shows minutes, seconds, frames. Hours only shown as needed. */
+			if (hours) {
+				rlen = BLI_snprintf(str, maxncpy, "%s%02d:%02d:%02d:%02d", neg, hours, minutes, seconds, frames);
+			}
+			else {
+				rlen = BLI_snprintf(str, maxncpy, "%s%02d:%02d:%02d", neg, minutes, seconds, frames);
+			}
+			break;
+		}
+		case USER_TIMECODE_MILLISECONDS:
+		{
+			/* reduced SMPTE. Instead of frames, milliseconds are shown */
+
+			/* precision of decimal part */
+			const int ms_dp = (power <= 0) ? (1 - power) : 1;
+
+			/* to get 2 digit whole-number part for seconds display
+			 * (i.e. 3 is for 2 digits + radix, on top of full length) */
+			const int s_pad = ms_dp + 3;
+
+			if (hours) {
+				rlen = BLI_snprintf(str, maxncpy, "%s%02d:%02d:%0*.*f", neg, hours, minutes, s_pad, ms_dp, time);
+			}
+			else {
+				rlen = BLI_snprintf(str, maxncpy, "%s%02d:%0*.*f", neg, minutes, s_pad,  ms_dp, time);
+			}
+			break;
+		}
+		case USER_TIMECODE_SECONDS_ONLY:
+		{
+			/* only show the original seconds display */
+			/* round to whole numbers if power is >= 1 (i.e. scale is coarse) */
+			if (power <= 0) {
+				rlen = BLI_snprintf(str, maxncpy, "%.*f", 1 - power, time_seconds);
+			}
+			else {
+				rlen = BLI_snprintf(str, maxncpy, "%d", iroundf(time_seconds));
+			}
+			break;
+		}
+		case USER_TIMECODE_SMPTE_FULL:
+		default:
+		{
+			/* full SMPTE format */
+			rlen = BLI_snprintf(str, maxncpy, "%s%02d:%02d:%02d:%02d", neg, hours, minutes, seconds, frames);
+			break;
+		}
+	}
+
+	return rlen;
+}
+
+
+/**
+ * Generate time string and store in \a str
+ *
+ * \param str  destination string
+ * \param maxncpy  maximum number of characters to copy ``sizeof(str)``
+ * \param power  special setting for #View2D grid drawing,
+ *        used to specify how detailed we need to be
+ * \param time_seconds  time total time in seconds
+ * \param seconds  time 

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list