Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/blenlib/intern')
-rw-r--r--source/blender/blenlib/intern/boxpack_2d.c4
-rw-r--r--source/blender/blenlib/intern/fileops.c243
-rw-r--r--source/blender/blenlib/intern/filereader_file.c80
-rw-r--r--source/blender/blenlib/intern/filereader_gzip.c108
-rw-r--r--source/blender/blenlib/intern/filereader_memory.c145
-rw-r--r--source/blender/blenlib/intern/filereader_zstd.c335
-rw-r--r--source/blender/blenlib/intern/freetypefont.c47
-rw-r--r--source/blender/blenlib/intern/math_base_inline.c7
-rw-r--r--source/blender/blenlib/intern/math_geom.c72
-rw-r--r--source/blender/blenlib/intern/math_vector_inline.c24
-rw-r--r--source/blender/blenlib/intern/path_util.c11
-rw-r--r--source/blender/blenlib/intern/polyfill_2d_beautify.c2
-rw-r--r--source/blender/blenlib/intern/scanfill.c22
-rw-r--r--source/blender/blenlib/intern/storage.c2
14 files changed, 856 insertions, 246 deletions
diff --git a/source/blender/blenlib/intern/boxpack_2d.c b/source/blender/blenlib/intern/boxpack_2d.c
index ea6c2d8d498..4a07f1134d0 100644
--- a/source/blender/blenlib/intern/boxpack_2d.c
+++ b/source/blender/blenlib/intern/boxpack_2d.c
@@ -409,8 +409,8 @@ void BLI_box_pack_2d(BoxPack *boxarray, const uint len, float *r_tot_x, float *r
for (i = 0; i < verts_pack_len && isect; i++) {
vert = &vs_ctx.vertarray[vertex_pack_indices[i]];
- /* printf("\ttesting vert %i %i %i %f %f\n", i,
- * vert->free, verts_pack_len, vert->x, vert->y); */
+ // printf("\ttesting vert %i %i %i %f %f\n", i,
+ // vert->free, verts_pack_len, vert->x, vert->y);
/* This vert has a free quadrant
* Test if we can place the box here
diff --git a/source/blender/blenlib/intern/fileops.c b/source/blender/blenlib/intern/fileops.c
index ac034d2b5cd..532a29b8147 100644
--- a/source/blender/blenlib/intern/fileops.c
+++ b/source/blender/blenlib/intern/fileops.c
@@ -31,6 +31,7 @@
#include <errno.h>
#include "zlib.h"
+#include "zstd.h"
#ifdef WIN32
# include "BLI_fileops_types.h"
@@ -61,200 +62,124 @@
#include "BLI_sys_types.h" /* for intptr_t support */
#include "BLI_utildefines.h"
-#if 0 /* UNUSED */
-/* gzip the file in from and write it to "to".
- * return -1 if zlib fails, -2 if the originating file does not exist
- * NOTE: will remove the "from" file
- */
-int BLI_file_gzip(const char *from, const char *to)
+size_t BLI_file_zstd_from_mem_at_pos(
+ void *buf, size_t len, FILE *file, size_t file_offset, int compression_level)
{
- char buffer[10240];
- int file;
- int readsize = 0;
- int rval = 0, err;
- gzFile gzfile;
+ fseek(file, file_offset, SEEK_SET);
- /* level 1 is very close to 3 (the default) in terms of file size,
- * but about twice as fast, best use for speedy saving - campbell */
- gzfile = BLI_gzopen(to, "wb1");
- if (gzfile == NULL) {
- return -1;
- }
- file = BLI_open(from, O_BINARY | O_RDONLY, 0);
- if (file == -1) {
- return -2;
- }
+ ZSTD_CCtx *ctx = ZSTD_createCCtx();
+ ZSTD_CCtx_setParameter(ctx, ZSTD_c_compressionLevel, compression_level);
+
+ ZSTD_inBuffer input = {buf, len, 0};
- while (1) {
- readsize = read(file, buffer, sizeof(buffer));
+ size_t out_len = ZSTD_CStreamOutSize();
+ void *out_buf = MEM_mallocN(out_len, __func__);
+ size_t total_written = 0;
- if (readsize < 0) {
- rval = -2; /* error happened in reading */
- fprintf(stderr, "Error reading file %s: %s.\n", from, strerror(errno));
+ /* Compress block and write it out until the input has been consumed. */
+ while (input.pos < input.size) {
+ ZSTD_outBuffer output = {out_buf, out_len, 0};
+ size_t ret = ZSTD_compressStream2(ctx, &output, &input, ZSTD_e_continue);
+ if (ZSTD_isError(ret)) {
break;
}
- else if (readsize == 0) {
- break; /* done reading */
+ if (fwrite(out_buf, 1, output.pos, file) != output.pos) {
+ break;
}
+ total_written += output.pos;
+ }
- if (gzwrite(gzfile, buffer, readsize) <= 0) {
- rval = -1; /* error happened in writing */
- fprintf(stderr, "Error writing gz file %s: %s.\n", to, gzerror(gzfile, &err));
+ /* Finalize the Zstd frame. */
+ size_t ret = 1;
+ while (ret != 0) {
+ ZSTD_outBuffer output = {out_buf, out_len, 0};
+ ret = ZSTD_compressStream2(ctx, &output, &input, ZSTD_e_end);
+ if (ZSTD_isError(ret)) {
+ break;
+ }
+ if (fwrite(out_buf, 1, output.pos, file) != output.pos) {
break;
}
+ total_written += output.pos;
}
- gzclose(gzfile);
- close(file);
+ MEM_freeN(out_buf);
+ ZSTD_freeCCtx(ctx);
- return rval;
+ return ZSTD_isError(ret) ? 0 : total_written;
}
-#endif
-/* gzip the file in from_file and write it to memory to_mem, at most size bytes.
- * return the unzipped size
- */
-char *BLI_file_ungzip_to_mem(const char *from_file, int *r_size)
+size_t BLI_file_unzstd_to_mem_at_pos(void *buf, size_t len, FILE *file, size_t file_offset)
{
- gzFile gzfile;
- int readsize, size, alloc_size = 0;
- char *mem = NULL;
- const int chunk_size = 512 * 1024;
+ fseek(file, file_offset, SEEK_SET);
- size = 0;
+ ZSTD_DCtx *ctx = ZSTD_createDCtx();
- gzfile = BLI_gzopen(from_file, "rb");
- for (;;) {
- if (mem == NULL) {
- mem = MEM_callocN(chunk_size, "BLI_ungzip_to_mem");
- alloc_size = chunk_size;
- }
- else {
- mem = MEM_reallocN(mem, size + chunk_size);
- alloc_size += chunk_size;
- }
+ size_t in_len = ZSTD_DStreamInSize();
+ void *in_buf = MEM_mallocN(in_len, __func__);
+ ZSTD_inBuffer input = {in_buf, in_len, 0};
- readsize = gzread(gzfile, mem + size, chunk_size);
- if (readsize > 0) {
- size += readsize;
- }
- else {
+ ZSTD_outBuffer output = {buf, len, 0};
+
+ size_t ret = 0;
+ /* Read and decompress chunks of input data until we have enough output. */
+ while (output.pos < output.size && !ZSTD_isError(ret)) {
+ input.size = fread(in_buf, 1, in_len, file);
+ if (input.size == 0) {
break;
}
- }
- gzclose(gzfile);
+ /* Consume input data until we run out or have enough output. */
+ input.pos = 0;
+ while (input.pos < input.size && output.pos < output.size) {
+ ret = ZSTD_decompressStream(ctx, &output, &input);
- if (size == 0) {
- MEM_freeN(mem);
- mem = NULL;
- }
- else if (alloc_size != size) {
- mem = MEM_reallocN(mem, size);
+ if (ZSTD_isError(ret)) {
+ break;
+ }
+ }
}
- *r_size = size;
+ MEM_freeN(in_buf);
+ ZSTD_freeDCtx(ctx);
- return mem;
+ return ZSTD_isError(ret) ? 0 : output.pos;
}
-#define CHUNK (256 * 1024)
-
-/* gzip byte array from memory and write it to file at certain position.
- * return size of gzip stream.
- */
-size_t BLI_gzip_mem_to_file_at_pos(
- void *buf, size_t len, FILE *file, size_t gz_stream_offset, int compression_level)
+bool BLI_file_magic_is_gzip(const char header[4])
{
- int ret, flush;
- unsigned have;
- z_stream strm;
- unsigned char out[CHUNK];
-
- BLI_fseek(file, gz_stream_offset, 0);
-
- strm.zalloc = Z_NULL;
- strm.zfree = Z_NULL;
- strm.opaque = Z_NULL;
- ret = deflateInit(&strm, compression_level);
- if (ret != Z_OK) {
- return 0;
- }
-
- strm.avail_in = len;
- strm.next_in = (Bytef *)buf;
- flush = Z_FINISH;
-
- do {
- strm.avail_out = CHUNK;
- strm.next_out = out;
- ret = deflate(&strm, flush);
- if (ret == Z_STREAM_ERROR) {
- return 0;
- }
- have = CHUNK - strm.avail_out;
- if (fwrite(out, 1, have, file) != have || ferror(file)) {
- deflateEnd(&strm);
- return 0;
- }
- } while (strm.avail_out == 0);
-
- if (strm.avail_in != 0 || ret != Z_STREAM_END) {
- return 0;
- }
-
- deflateEnd(&strm);
- return (size_t)strm.total_out;
+ /* GZIP itself starts with the magic bytes 0x1f 0x8b.
+ * The third byte indicates the compression method, which is 0x08 for DEFLATE. */
+ return header[0] == 0x1f && header[1] == 0x8b && header[2] == 0x08;
}
-/* read and decompress gzip stream from file at certain position to buffer.
- * return size of decompressed data.
- */
-size_t BLI_ungzip_file_to_mem_at_pos(void *buf, size_t len, FILE *file, size_t gz_stream_offset)
+bool BLI_file_magic_is_zstd(const char header[4])
{
- int ret;
- z_stream strm;
- size_t chunk = 256 * 1024;
- unsigned char in[CHUNK];
-
- BLI_fseek(file, gz_stream_offset, 0);
-
- strm.zalloc = Z_NULL;
- strm.zfree = Z_NULL;
- strm.opaque = Z_NULL;
- strm.avail_in = 0;
- strm.next_in = Z_NULL;
- ret = inflateInit(&strm);
- if (ret != Z_OK) {
- return 0;
+ /* ZSTD files consist of concatenated frames, each either a Zstd frame or a skippable frame.
+ * Both types of frames start with a magic number: 0xFD2FB528 for Zstd frames and 0x184D2A5*
+ * for skippable frames, with the * being anything from 0 to F.
+ *
+ * To check whether a file is Zstd-compressed, we just check whether the first frame matches
+ * either. Seeking through the file until a Zstd frame is found would make things more
+ * complicated and the probability of a false positive is rather low anyways.
+ *
+ * Note that LZ4 uses a compatible format, so even though its compressed frames have a
+ * different magic number, a valid LZ4 file might also start with a skippable frame matching
+ * the second check here.
+ *
+ * For more details, see https://github.com/facebook/zstd/blob/dev/doc/zstd_compression_format.md
+ */
+
+ uint32_t magic = *((uint32_t *)header);
+ if (magic == 0xFD2FB528) {
+ return true;
}
-
- do {
- strm.avail_in = fread(in, 1, chunk, file);
- strm.next_in = in;
- if (ferror(file)) {
- inflateEnd(&strm);
- return 0;
- }
-
- do {
- strm.avail_out = len;
- strm.next_out = (Bytef *)buf + strm.total_out;
-
- ret = inflate(&strm, Z_NO_FLUSH);
- if (ret == Z_STREAM_ERROR) {
- return 0;
- }
- } while (strm.avail_out == 0);
-
- } while (ret != Z_STREAM_END);
-
- inflateEnd(&strm);
- return (size_t)strm.total_out;
+ if ((magic >> 4) == 0x184D2A5) {
+ return true;
+ }
+ return false;
}
-#undef CHUNK
-
/**
* Returns true if the file with the specified name can be written.
* This implementation uses access(2), which makes the check according
diff --git a/source/blender/blenlib/intern/filereader_file.c b/source/blender/blenlib/intern/filereader_file.c
new file mode 100644
index 00000000000..3a833871e27
--- /dev/null
+++ b/source/blender/blenlib/intern/filereader_file.c
@@ -0,0 +1,80 @@
+/*
+ * 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) 2004-2021 Blender Foundation
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup bli
+ */
+
+#ifndef WIN32
+# include <unistd.h> /* for read close */
+#else
+# include "BLI_winstuff.h"
+# include "winsock2.h"
+# include <io.h> /* for open close read */
+#endif
+
+#include "BLI_blenlib.h"
+#include "BLI_filereader.h"
+
+#include "MEM_guardedalloc.h"
+
+typedef struct {
+ FileReader reader;
+
+ int filedes;
+} RawFileReader;
+
+static ssize_t file_read(FileReader *reader, void *buffer, size_t size)
+{
+ RawFileReader *rawfile = (RawFileReader *)reader;
+ ssize_t readsize = read(rawfile->filedes, buffer, size);
+
+ if (readsize >= 0) {
+ rawfile->reader.offset += readsize;
+ }
+
+ return readsize;
+}
+
+static off64_t file_seek(FileReader *reader, off64_t offset, int whence)
+{
+ RawFileReader *rawfile = (RawFileReader *)reader;
+ rawfile->reader.offset = BLI_lseek(rawfile->filedes, offset, whence);
+ return rawfile->reader.offset;
+}
+
+static void file_close(FileReader *reader)
+{
+ RawFileReader *rawfile = (RawFileReader *)reader;
+ close(rawfile->filedes);
+ MEM_freeN(rawfile);
+}
+
+FileReader *BLI_filereader_new_file(int filedes)
+{
+ RawFileReader *rawfile = MEM_callocN(sizeof(RawFileReader), __func__);
+
+ rawfile->filedes = filedes;
+
+ rawfile->reader.read = file_read;
+ rawfile->reader.seek = file_seek;
+ rawfile->reader.close = file_close;
+
+ return (FileReader *)rawfile;
+}
diff --git a/source/blender/blenlib/intern/filereader_gzip.c b/source/blender/blenlib/intern/filereader_gzip.c
new file mode 100644
index 00000000000..72eb153a8b9
--- /dev/null
+++ b/source/blender/blenlib/intern/filereader_gzip.c
@@ -0,0 +1,108 @@
+/*
+ * 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) 2004-2021 Blender Foundation
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup bli
+ */
+
+#include <zlib.h>
+
+#include "BLI_blenlib.h"
+#include "BLI_filereader.h"
+
+#include "MEM_guardedalloc.h"
+
+typedef struct {
+ FileReader reader;
+
+ FileReader *base;
+
+ z_stream strm;
+
+ void *in_buf;
+ size_t in_size;
+} GzipReader;
+
+static ssize_t gzip_read(FileReader *reader, void *buffer, size_t size)
+{
+ GzipReader *gzip = (GzipReader *)reader;
+
+ gzip->strm.avail_out = size;
+ gzip->strm.next_out = buffer;
+
+ while (gzip->strm.avail_out > 0) {
+ if (gzip->strm.avail_in == 0) {
+ /* Ran out of buffered input data, read some more. */
+ size_t readsize = gzip->base->read(gzip->base, gzip->in_buf, gzip->in_size);
+
+ if (readsize > 0) {
+ /* We got some data, so mark the buffer as refilled. */
+ gzip->strm.avail_in = readsize;
+ gzip->strm.next_in = gzip->in_buf;
+ }
+ else {
+ /* The underlying file is EOF, so return as much as we can. */
+ break;
+ }
+ }
+
+ int ret = inflate(&gzip->strm, Z_NO_FLUSH);
+
+ if (ret != Z_OK && ret != Z_BUF_ERROR) {
+ break;
+ }
+ }
+
+ ssize_t read_len = size - gzip->strm.avail_out;
+ gzip->reader.offset += read_len;
+ return read_len;
+}
+
+static void gzip_close(FileReader *reader)
+{
+ GzipReader *gzip = (GzipReader *)reader;
+
+ if (inflateEnd(&gzip->strm) != Z_OK) {
+ printf("close gzip stream error\n");
+ }
+ MEM_freeN((void *)gzip->in_buf);
+
+ gzip->base->close(gzip->base);
+ MEM_freeN(gzip);
+}
+
+FileReader *BLI_filereader_new_gzip(FileReader *base)
+{
+ GzipReader *gzip = MEM_callocN(sizeof(GzipReader), __func__);
+ gzip->base = base;
+
+ if (inflateInit2(&gzip->strm, 16 + MAX_WBITS) != Z_OK) {
+ MEM_freeN(gzip);
+ return NULL;
+ }
+
+ gzip->in_size = 256 * 2014;
+ gzip->in_buf = MEM_mallocN(gzip->in_size, "gzip in buf");
+
+ gzip->reader.read = gzip_read;
+ gzip->reader.seek = NULL;
+ gzip->reader.close = gzip_close;
+
+ return (FileReader *)gzip;
+}
diff --git a/source/blender/blenlib/intern/filereader_memory.c b/source/blender/blenlib/intern/filereader_memory.c
new file mode 100644
index 00000000000..150fed7d1cc
--- /dev/null
+++ b/source/blender/blenlib/intern/filereader_memory.c
@@ -0,0 +1,145 @@
+/*
+ * 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) 2004-2021 Blender Foundation
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup bli
+ */
+
+#include <string.h>
+
+#include "BLI_blenlib.h"
+#include "BLI_filereader.h"
+#include "BLI_mmap.h"
+
+#include "MEM_guardedalloc.h"
+
+/* This file implements both memory-backed and memory-mapped-file-backed reading. */
+typedef struct {
+ FileReader reader;
+
+ const char *data;
+ BLI_mmap_file *mmap;
+ size_t length;
+} MemoryReader;
+
+static ssize_t memory_read_raw(FileReader *reader, void *buffer, size_t size)
+{
+ MemoryReader *mem = (MemoryReader *)reader;
+
+ /* Don't read more bytes than there are available in the buffer. */
+ size_t readsize = MIN2(size, (size_t)(mem->length - mem->reader.offset));
+
+ memcpy(buffer, mem->data + mem->reader.offset, readsize);
+ mem->reader.offset += readsize;
+
+ return readsize;
+}
+
+static off64_t memory_seek(FileReader *reader, off64_t offset, int whence)
+{
+ MemoryReader *mem = (MemoryReader *)reader;
+
+ off64_t new_pos;
+ if (whence == SEEK_CUR) {
+ new_pos = mem->reader.offset + offset;
+ }
+ else if (whence == SEEK_SET) {
+ new_pos = offset;
+ }
+ else if (whence == SEEK_END) {
+ new_pos = mem->length + offset;
+ }
+ else {
+ return -1;
+ }
+
+ if (new_pos < 0 || new_pos > mem->length) {
+ return -1;
+ }
+
+ mem->reader.offset = new_pos;
+ return mem->reader.offset;
+}
+
+static void memory_close_raw(FileReader *reader)
+{
+ MEM_freeN(reader);
+}
+
+FileReader *BLI_filereader_new_memory(const void *data, size_t len)
+{
+ MemoryReader *mem = MEM_callocN(sizeof(MemoryReader), __func__);
+
+ mem->data = (const char *)data;
+ mem->length = len;
+
+ mem->reader.read = memory_read_raw;
+ mem->reader.seek = memory_seek;
+ mem->reader.close = memory_close_raw;
+
+ return (FileReader *)mem;
+}
+
+/* Memory-mapped file reading.
+ * By using `mmap()`, we can map a file so that it can be treated like normal memory,
+ * meaning that we can just read from it with `memcpy()` etc.
+ * This avoids system call overhead and can significantly speed up file loading.
+ */
+
+static ssize_t memory_read_mmap(FileReader *reader, void *buffer, size_t size)
+{
+ MemoryReader *mem = (MemoryReader *)reader;
+
+ /* Don't read more bytes than there are available in the buffer. */
+ size_t readsize = MIN2(size, (size_t)(mem->length - mem->reader.offset));
+
+ if (!BLI_mmap_read(mem->mmap, buffer, mem->reader.offset, readsize)) {
+ return 0;
+ }
+
+ mem->reader.offset += readsize;
+
+ return readsize;
+}
+
+static void memory_close_mmap(FileReader *reader)
+{
+ MemoryReader *mem = (MemoryReader *)reader;
+ BLI_mmap_free(mem->mmap);
+ MEM_freeN(mem);
+}
+
+FileReader *BLI_filereader_new_mmap(int filedes)
+{
+ BLI_mmap_file *mmap = BLI_mmap_open(filedes);
+ if (mmap == NULL) {
+ return NULL;
+ }
+
+ MemoryReader *mem = MEM_callocN(sizeof(MemoryReader), __func__);
+
+ mem->mmap = mmap;
+ mem->length = BLI_lseek(filedes, 0, SEEK_END);
+
+ mem->reader.read = memory_read_mmap;
+ mem->reader.seek = memory_seek;
+ mem->reader.close = memory_close_mmap;
+
+ return (FileReader *)mem;
+}
diff --git a/source/blender/blenlib/intern/filereader_zstd.c b/source/blender/blenlib/intern/filereader_zstd.c
new file mode 100644
index 00000000000..785a40cd1a1
--- /dev/null
+++ b/source/blender/blenlib/intern/filereader_zstd.c
@@ -0,0 +1,335 @@
+/*
+ * 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) 2021 Blender Foundation
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup bli
+ */
+
+#include <string.h>
+#include <zstd.h>
+
+#include "BLI_blenlib.h"
+#include "BLI_endian_switch.h"
+#include "BLI_filereader.h"
+#include "BLI_math_base.h"
+
+#include "MEM_guardedalloc.h"
+
+typedef struct {
+ FileReader reader;
+
+ FileReader *base;
+
+ ZSTD_DCtx *ctx;
+ ZSTD_inBuffer in_buf;
+ size_t in_buf_max_size;
+
+ struct {
+ int num_frames;
+ size_t *compressed_ofs;
+ size_t *uncompressed_ofs;
+
+ char *cached_content;
+ int cached_frame;
+ } seek;
+} ZstdReader;
+
+static bool zstd_read_u32(FileReader *base, uint32_t *val)
+{
+ if (base->read(base, val, sizeof(uint32_t)) != sizeof(uint32_t)) {
+ return false;
+ }
+#ifdef __BIG_ENDIAN__
+ BLI_endian_switch_uint32(val);
+#endif
+ return true;
+}
+
+static bool zstd_read_seek_table(ZstdReader *zstd)
+{
+ FileReader *base = zstd->base;
+
+ /* The seek table frame is at the end of the file, so seek there
+ * and verify that there is enough data. */
+ if (base->seek(base, -4, SEEK_END) < 13) {
+ return false;
+ }
+ uint32_t magic;
+ if (!zstd_read_u32(base, &magic) || magic != 0x8F92EAB1) {
+ return false;
+ }
+
+ uint8_t flags;
+ if (base->seek(base, -5, SEEK_END) < 0 || base->read(base, &flags, 1) != 1) {
+ return false;
+ }
+ /* Bit 7 indicates checksums. Bits 5 and 6 must be zero. */
+ bool has_checksums = (flags & 0x80);
+ if (flags & 0x60) {
+ return false;
+ }
+
+ uint32_t num_frames;
+ if (base->seek(base, -9, SEEK_END) < 0 || !zstd_read_u32(base, &num_frames)) {
+ return false;
+ }
+
+ /* Each frame has either 2 or 3 uint32_t, and after that we have
+ * num_frames, flags and magic for another 9 bytes. */
+ uint32_t expected_frame_length = num_frames * (has_checksums ? 12 : 8) + 9;
+ /* The frame starts with another magic number and its length, but these
+ * two fields are not included when counting length. */
+ off64_t frame_start_ofs = 8 + expected_frame_length;
+ /* Sanity check: Before the start of the seek table frame,
+ * there must be num_frames frames, each of which at least 8 bytes long. */
+ off64_t seek_frame_start = base->seek(base, -frame_start_ofs, SEEK_END);
+ if (seek_frame_start < num_frames * 8) {
+ return false;
+ }
+
+ if (!zstd_read_u32(base, &magic) || magic != 0x184D2A5E) {
+ return false;
+ }
+
+ uint32_t frame_length;
+ if (!zstd_read_u32(base, &frame_length) || frame_length != expected_frame_length) {
+ return false;
+ }
+
+ zstd->seek.num_frames = num_frames;
+ zstd->seek.compressed_ofs = MEM_malloc_arrayN(num_frames + 1, sizeof(size_t), __func__);
+ zstd->seek.uncompressed_ofs = MEM_malloc_arrayN(num_frames + 1, sizeof(size_t), __func__);
+
+ size_t compressed_ofs = 0;
+ size_t uncompressed_ofs = 0;
+ for (int i = 0; i < num_frames; i++) {
+ uint32_t compressed_size, uncompressed_size;
+ if (!zstd_read_u32(base, &compressed_size) || !zstd_read_u32(base, &uncompressed_size)) {
+ break;
+ }
+ if (has_checksums && base->seek(base, 4, SEEK_CUR) < 0) {
+ break;
+ }
+ zstd->seek.compressed_ofs[i] = compressed_ofs;
+ zstd->seek.uncompressed_ofs[i] = uncompressed_ofs;
+ compressed_ofs += compressed_size;
+ uncompressed_ofs += uncompressed_size;
+ }
+ zstd->seek.compressed_ofs[num_frames] = compressed_ofs;
+ zstd->seek.uncompressed_ofs[num_frames] = uncompressed_ofs;
+
+ /* Seek to the end of the previous frame for the following BHead frame detection. */
+ if (seek_frame_start != compressed_ofs || base->seek(base, seek_frame_start, SEEK_SET) < 0) {
+ MEM_freeN(zstd->seek.compressed_ofs);
+ MEM_freeN(zstd->seek.uncompressed_ofs);
+ memset(&zstd->seek, 0, sizeof(zstd->seek));
+ return false;
+ }
+
+ zstd->seek.cached_frame = -1;
+
+ return true;
+}
+
+/* Find out which frame contains the given position in the uncompressed stream.
+ * Basically just bisection. */
+static int zstd_frame_from_pos(ZstdReader *zstd, size_t pos)
+{
+ int low = 0, high = zstd->seek.num_frames;
+
+ if (pos >= zstd->seek.uncompressed_ofs[zstd->seek.num_frames]) {
+ return -1;
+ }
+
+ while (low + 1 < high) {
+ int mid = low + ((high - low) >> 1);
+ if (zstd->seek.uncompressed_ofs[mid] <= pos) {
+ low = mid;
+ }
+ else {
+ high = mid;
+ }
+ }
+
+ return low;
+}
+
+/* Ensure that the currently loaded frame is the correct one. */
+static const char *zstd_ensure_cache(ZstdReader *zstd, int frame)
+{
+ if (zstd->seek.cached_frame == frame) {
+ /* Cached frame matches, so just return it. */
+ return zstd->seek.cached_content;
+ }
+
+ /* Cached frame doesn't match, so discard it and cache the wanted one onstead. */
+ MEM_SAFE_FREE(zstd->seek.cached_content);
+
+ size_t compressed_size = zstd->seek.compressed_ofs[frame + 1] - zstd->seek.compressed_ofs[frame];
+ size_t uncompressed_size = zstd->seek.uncompressed_ofs[frame + 1] -
+ zstd->seek.uncompressed_ofs[frame];
+
+ char *uncompressed_data = MEM_mallocN(uncompressed_size, __func__);
+ char *compressed_data = MEM_mallocN(compressed_size, __func__);
+ if (zstd->base->seek(zstd->base, zstd->seek.compressed_ofs[frame], SEEK_SET) < 0 ||
+ zstd->base->read(zstd->base, compressed_data, compressed_size) < compressed_size) {
+ MEM_freeN(compressed_data);
+ MEM_freeN(uncompressed_data);
+ return NULL;
+ }
+
+ size_t res = ZSTD_decompressDCtx(
+ zstd->ctx, uncompressed_data, uncompressed_size, compressed_data, compressed_size);
+ MEM_freeN(compressed_data);
+ if (ZSTD_isError(res) || res < uncompressed_size) {
+ MEM_freeN(uncompressed_data);
+ return NULL;
+ }
+
+ zstd->seek.cached_frame = frame;
+ zstd->seek.cached_content = uncompressed_data;
+ return uncompressed_data;
+}
+
+static ssize_t zstd_read_seekable(FileReader *reader, void *buffer, size_t size)
+{
+ ZstdReader *zstd = (ZstdReader *)reader;
+
+ size_t end_offset = zstd->reader.offset + size, read_len = 0;
+ while (zstd->reader.offset < end_offset) {
+ int frame = zstd_frame_from_pos(zstd, zstd->reader.offset);
+ if (frame < 0) {
+ /* EOF is reached, so return as much as we can. */
+ break;
+ }
+
+ const char *framedata = zstd_ensure_cache(zstd, frame);
+ if (framedata == NULL) {
+ /* Error while reading the frame, so return as much as we can. */
+ break;
+ }
+
+ size_t frame_end_offset = min_zz(zstd->seek.uncompressed_ofs[frame + 1], end_offset);
+ size_t frame_read_len = frame_end_offset - zstd->reader.offset;
+
+ size_t offset_in_frame = zstd->reader.offset - zstd->seek.uncompressed_ofs[frame];
+ memcpy((char *)buffer + read_len, framedata + offset_in_frame, frame_read_len);
+ read_len += frame_read_len;
+ zstd->reader.offset = frame_end_offset;
+ }
+
+ return read_len;
+}
+
+static off64_t zstd_seek(FileReader *reader, off64_t offset, int whence)
+{
+ ZstdReader *zstd = (ZstdReader *)reader;
+ off64_t new_pos;
+ if (whence == SEEK_SET) {
+ new_pos = offset;
+ }
+ else if (whence == SEEK_END) {
+ new_pos = zstd->seek.uncompressed_ofs[zstd->seek.num_frames] + offset;
+ }
+ else {
+ new_pos = zstd->reader.offset + offset;
+ }
+
+ if (new_pos < 0 || new_pos > zstd->seek.uncompressed_ofs[zstd->seek.num_frames]) {
+ return -1;
+ }
+ zstd->reader.offset = new_pos;
+ return zstd->reader.offset;
+}
+
+static ssize_t zstd_read(FileReader *reader, void *buffer, size_t size)
+{
+ ZstdReader *zstd = (ZstdReader *)reader;
+ ZSTD_outBuffer output = {buffer, size, 0};
+
+ while (output.pos < output.size) {
+ if (zstd->in_buf.pos == zstd->in_buf.size) {
+ /* Ran out of buffered input data, read some more. */
+ zstd->in_buf.pos = 0;
+ ssize_t readsize = zstd->base->read(
+ zstd->base, (char *)zstd->in_buf.src, zstd->in_buf_max_size);
+
+ if (readsize > 0) {
+ /* We got some data, so mark the buffer as refilled. */
+ zstd->in_buf.size = readsize;
+ }
+ else {
+ /* The underlying file is EOF, so return as much as we can. */
+ break;
+ }
+ }
+
+ if (ZSTD_isError(ZSTD_decompressStream(zstd->ctx, &output, &zstd->in_buf))) {
+ break;
+ }
+ }
+
+ zstd->reader.offset += output.pos;
+ return output.pos;
+}
+
+static void zstd_close(FileReader *reader)
+{
+ ZstdReader *zstd = (ZstdReader *)reader;
+
+ ZSTD_freeDCtx(zstd->ctx);
+ if (zstd->reader.seek) {
+ MEM_freeN(zstd->seek.uncompressed_ofs);
+ MEM_freeN(zstd->seek.compressed_ofs);
+ MEM_freeN(zstd->seek.cached_content);
+ }
+ else {
+ MEM_freeN((void *)zstd->in_buf.src);
+ }
+
+ zstd->base->close(zstd->base);
+ MEM_freeN(zstd);
+}
+
+FileReader *BLI_filereader_new_zstd(FileReader *base)
+{
+ ZstdReader *zstd = MEM_callocN(sizeof(ZstdReader), __func__);
+
+ zstd->ctx = ZSTD_createDCtx();
+ zstd->base = base;
+
+ if (zstd_read_seek_table(zstd)) {
+ zstd->reader.read = zstd_read_seekable;
+ zstd->reader.seek = zstd_seek;
+ }
+ else {
+ zstd->reader.read = zstd_read;
+ zstd->reader.seek = NULL;
+
+ zstd->in_buf_max_size = ZSTD_DStreamInSize();
+ zstd->in_buf.src = MEM_mallocN(zstd->in_buf_max_size, "zstd in buf");
+ zstd->in_buf.size = zstd->in_buf_max_size;
+ /* This signals that the buffer has run out,
+ * which will make the read function refill it on the first call. */
+ zstd->in_buf.pos = zstd->in_buf_max_size;
+ }
+ zstd->reader.close = zstd_close;
+
+ return (FileReader *)zstd;
+}
diff --git a/source/blender/blenlib/intern/freetypefont.c b/source/blender/blenlib/intern/freetypefont.c
index 98da85e3a8c..a8b50b66f5f 100644
--- a/source/blender/blenlib/intern/freetypefont.c
+++ b/source/blender/blenlib/intern/freetypefont.c
@@ -40,6 +40,7 @@
#include "BLI_listbase.h"
#include "BLI_math.h"
#include "BLI_string.h"
+#include "BLI_string_utf8.h"
#include "BLI_utildefines.h"
#include "BLI_vfontdata.h"
@@ -286,7 +287,6 @@ static VFontData *objfnt_to_ftvfontdata(PackedFile *pf)
const FT_ULong charcode_reserve = 256;
FT_ULong charcode = 0, lcode;
FT_UInt glyph_index;
- const char *fontname;
VFontData *vfd;
/* load the freetype font */
@@ -299,36 +299,29 @@ static VFontData *objfnt_to_ftvfontdata(PackedFile *pf)
/* allocate blender font */
vfd = MEM_callocN(sizeof(*vfd), "FTVFontData");
- /* get the name */
- fontname = FT_Get_Postscript_Name(face);
- BLI_strncpy(vfd->name, (fontname == NULL) ? "" : fontname, sizeof(vfd->name));
+ /* Get the name. */
+ if (face->family_name) {
+ BLI_snprintf(vfd->name, sizeof(vfd->name), "%s %s", face->family_name, face->style_name);
+ BLI_utf8_invalid_strip(vfd->name, strlen(vfd->name));
+ }
+
+ /* Select a character map. */
+ err = FT_Select_Charmap(face, FT_ENCODING_UNICODE);
+ if (err) {
+ err = FT_Select_Charmap(face, FT_ENCODING_APPLE_ROMAN);
+ }
+ if (err && face->num_charmaps > 0) {
+ err = FT_Select_Charmap(face, face->charmaps[0]->encoding);
+ }
+ if (err) {
+ FT_Done_Face(face);
+ MEM_freeN(vfd);
+ return NULL;
+ }
/* Extract the first 256 character from TTF */
lcode = charcode = FT_Get_First_Char(face, &glyph_index);
- /* No `charmap` found from the TTF so we need to figure it out. */
- if (glyph_index == 0) {
- FT_CharMap found = NULL;
- FT_CharMap charmap;
- int n;
-
- for (n = 0; n < face->num_charmaps; n++) {
- charmap = face->charmaps[n];
- if (charmap->encoding == FT_ENCODING_APPLE_ROMAN) {
- found = charmap;
- break;
- }
- }
-
- err = FT_Set_Charmap(face, found);
-
- if (err) {
- return NULL;
- }
-
- lcode = charcode = FT_Get_First_Char(face, &glyph_index);
- }
-
/* Blender default BFont is not "complete". */
const bool complete_font = (face->ascender != 0) && (face->descender != 0) &&
(face->ascender != face->descender);
diff --git a/source/blender/blenlib/intern/math_base_inline.c b/source/blender/blenlib/intern/math_base_inline.c
index 6e3846e59c6..a80c495ecf3 100644
--- a/source/blender/blenlib/intern/math_base_inline.c
+++ b/source/blender/blenlib/intern/math_base_inline.c
@@ -199,6 +199,13 @@ MINLINE float scalenorm(float a, float b, float x)
return (x * (b - a)) + a;
}
+/* Map a normalized value, i.e. from interval [0, 1] to interval [a, b]. */
+MINLINE double scalenormd(double a, double b, double x)
+{
+ BLI_assert(x <= 1 && x >= 0);
+ return (x * (b - a)) + a;
+}
+
/* Used for zoom values. */
MINLINE float power_of_2(float val)
{
diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c
index 803291e4a3b..8afb6b5a2be 100644
--- a/source/blender/blenlib/intern/math_geom.c
+++ b/source/blender/blenlib/intern/math_geom.c
@@ -1787,7 +1787,7 @@ bool isect_ray_tri_v3(const float ray_origin[3],
}
*r_lambda = f * dot_v3v3(e2, q);
- if ((*r_lambda < 0.0f)) {
+ if (*r_lambda < 0.0f) {
return false;
}
@@ -1864,7 +1864,7 @@ bool isect_ray_tri_epsilon_v3(const float ray_origin[3],
}
*r_lambda = f * dot_v3v3(e2, q);
- if ((*r_lambda < 0.0f)) {
+ if (*r_lambda < 0.0f) {
return false;
}
@@ -2024,7 +2024,7 @@ bool isect_ray_tri_threshold_v3(const float ray_origin[3],
cross_v3_v3v3(q, s, e1);
*r_lambda = f * dot_v3v3(e2, q);
- if ((*r_lambda < 0.0f)) {
+ if (*r_lambda < 0.0f) {
return false;
}
@@ -3325,7 +3325,7 @@ bool isect_ray_aabb_v3_simple(const float orig[3],
t[5] = (double)(bb_max[2] - orig[2]) * invdirz;
hit_dist[0] = (float)fmax(fmax(fmin(t[0], t[1]), fmin(t[2], t[3])), fmin(t[4], t[5]));
hit_dist[1] = (float)fmin(fmin(fmax(t[0], t[1]), fmax(t[2], t[3])), fmax(t[4], t[5]));
- if ((hit_dist[1] < 0.0f || hit_dist[0] > hit_dist[1])) {
+ if ((hit_dist[1] < 0.0f) || (hit_dist[0] > hit_dist[1])) {
return false;
}
@@ -4962,7 +4962,7 @@ void planes_from_projmat(const float mat[4][4],
}
}
-void projmat_dimensions(const float projmat[4][4],
+void projmat_dimensions(const float winmat[4][4],
float *r_left,
float *r_right,
float *r_bottom,
@@ -4970,27 +4970,27 @@ void projmat_dimensions(const float projmat[4][4],
float *r_near,
float *r_far)
{
- bool is_persp = projmat[3][3] == 0.0f;
-
+ const bool is_persp = winmat[3][3] == 0.0f;
if (is_persp) {
- *r_left = (projmat[2][0] - 1.0f) / projmat[0][0];
- *r_right = (projmat[2][0] + 1.0f) / projmat[0][0];
- *r_bottom = (projmat[2][1] - 1.0f) / projmat[1][1];
- *r_top = (projmat[2][1] + 1.0f) / projmat[1][1];
- *r_near = projmat[3][2] / (projmat[2][2] - 1.0f);
- *r_far = projmat[3][2] / (projmat[2][2] + 1.0f);
+ const float near = winmat[3][2] / (winmat[2][2] - 1.0f);
+ *r_left = near * ((winmat[2][0] - 1.0f) / winmat[0][0]);
+ *r_right = near * ((winmat[2][0] + 1.0f) / winmat[0][0]);
+ *r_bottom = near * ((winmat[2][1] - 1.0f) / winmat[1][1]);
+ *r_top = near * ((winmat[2][1] + 1.0f) / winmat[1][1]);
+ *r_near = near;
+ *r_far = winmat[3][2] / (winmat[2][2] + 1.0f);
}
else {
- *r_left = (-projmat[3][0] - 1.0f) / projmat[0][0];
- *r_right = (-projmat[3][0] + 1.0f) / projmat[0][0];
- *r_bottom = (-projmat[3][1] - 1.0f) / projmat[1][1];
- *r_top = (-projmat[3][1] + 1.0f) / projmat[1][1];
- *r_near = (projmat[3][2] + 1.0f) / projmat[2][2];
- *r_far = (projmat[3][2] - 1.0f) / projmat[2][2];
+ *r_left = (-winmat[3][0] - 1.0f) / winmat[0][0];
+ *r_right = (-winmat[3][0] + 1.0f) / winmat[0][0];
+ *r_bottom = (-winmat[3][1] - 1.0f) / winmat[1][1];
+ *r_top = (-winmat[3][1] + 1.0f) / winmat[1][1];
+ *r_near = (winmat[3][2] + 1.0f) / winmat[2][2];
+ *r_far = (winmat[3][2] - 1.0f) / winmat[2][2];
}
}
-void projmat_dimensions_db(const float projmat_fl[4][4],
+void projmat_dimensions_db(const float winmat_fl[4][4],
double *r_left,
double *r_right,
double *r_bottom,
@@ -4998,26 +4998,26 @@ void projmat_dimensions_db(const float projmat_fl[4][4],
double *r_near,
double *r_far)
{
- double projmat[4][4];
- copy_m4d_m4(projmat, projmat_fl);
-
- bool is_persp = projmat[3][3] == 0.0f;
+ double winmat[4][4];
+ copy_m4d_m4(winmat, winmat_fl);
+ const bool is_persp = winmat[3][3] == 0.0f;
if (is_persp) {
- *r_left = (projmat[2][0] - 1.0) / projmat[0][0];
- *r_right = (projmat[2][0] + 1.0) / projmat[0][0];
- *r_bottom = (projmat[2][1] - 1.0) / projmat[1][1];
- *r_top = (projmat[2][1] + 1.0) / projmat[1][1];
- *r_near = projmat[3][2] / (projmat[2][2] - 1.0);
- *r_far = projmat[3][2] / (projmat[2][2] + 1.0);
+ const double near = winmat[3][2] / (winmat[2][2] - 1.0);
+ *r_left = near * ((winmat[2][0] - 1.0) / winmat[0][0]);
+ *r_right = near * ((winmat[2][0] + 1.0) / winmat[0][0]);
+ *r_bottom = near * ((winmat[2][1] - 1.0) / winmat[1][1]);
+ *r_top = near * ((winmat[2][1] + 1.0) / winmat[1][1]);
+ *r_near = near;
+ *r_far = winmat[3][2] / (winmat[2][2] + 1.0);
}
else {
- *r_left = (-projmat[3][0] - 1.0) / projmat[0][0];
- *r_right = (-projmat[3][0] + 1.0) / projmat[0][0];
- *r_bottom = (-projmat[3][1] - 1.0) / projmat[1][1];
- *r_top = (-projmat[3][1] + 1.0) / projmat[1][1];
- *r_near = (projmat[3][2] + 1.0) / projmat[2][2];
- *r_far = (projmat[3][2] - 1.0) / projmat[2][2];
+ *r_left = (-winmat[3][0] - 1.0) / winmat[0][0];
+ *r_right = (-winmat[3][0] + 1.0) / winmat[0][0];
+ *r_bottom = (-winmat[3][1] - 1.0) / winmat[1][1];
+ *r_top = (-winmat[3][1] + 1.0) / winmat[1][1];
+ *r_near = (winmat[3][2] + 1.0) / winmat[2][2];
+ *r_far = (winmat[3][2] - 1.0) / winmat[2][2];
}
}
diff --git a/source/blender/blenlib/intern/math_vector_inline.c b/source/blender/blenlib/intern/math_vector_inline.c
index 55f7a152b83..ddfdaffb706 100644
--- a/source/blender/blenlib/intern/math_vector_inline.c
+++ b/source/blender/blenlib/intern/math_vector_inline.c
@@ -847,6 +847,19 @@ MINLINE void invert_v3(float r[3])
r[2] = 1.0f / r[2];
}
+MINLINE void invert_v3_safe(float r[3])
+{
+ if (r[0] != 0.0f) {
+ r[0] = 1.0f / r[0];
+ }
+ if (r[1] != 0.0f) {
+ r[1] = 1.0f / r[1];
+ }
+ if (r[2] != 0.0f) {
+ r[2] = 1.0f / r[2];
+ }
+}
+
MINLINE void abs_v2(float r[2])
{
r[0] = fabsf(r[0]);
@@ -1132,6 +1145,9 @@ MINLINE float len_v3v3(const float a[3], const float b[3])
return len_v3(d);
}
+/**
+ * \note any vectors containing `nan` will be zeroed out.
+ */
MINLINE float normalize_v2_v2_length(float r[2], const float a[2], const float unit_length)
{
float d = dot_v2v2(a, a);
@@ -1141,6 +1157,7 @@ MINLINE float normalize_v2_v2_length(float r[2], const float a[2], const float u
mul_v2_v2fl(r, a, unit_length / d);
}
else {
+ /* Either the vector is small or one of it's values contained `nan`. */
zero_v2(r);
d = 0.0f;
}
@@ -1162,17 +1179,20 @@ MINLINE float normalize_v2_length(float n[2], const float unit_length)
return normalize_v2_v2_length(n, n, unit_length);
}
+/**
+ * \note any vectors containing `nan` will be zeroed out.
+ */
MINLINE float normalize_v3_v3_length(float r[3], const float a[3], const float unit_length)
{
float d = dot_v3v3(a, a);
- /* a larger value causes normalize errors in a
- * scaled down models with camera extreme close */
+ /* A larger value causes normalize errors in a scaled down models with camera extreme close. */
if (d > 1.0e-35f) {
d = sqrtf(d);
mul_v3_v3fl(r, a, unit_length / d);
}
else {
+ /* Either the vector is small or one of it's values contained `nan`. */
zero_v3(r);
d = 0.0f;
}
diff --git a/source/blender/blenlib/intern/path_util.c b/source/blender/blenlib/intern/path_util.c
index 4d0dc43ed1e..4d0678035ba 100644
--- a/source/blender/blenlib/intern/path_util.c
+++ b/source/blender/blenlib/intern/path_util.c
@@ -1102,12 +1102,9 @@ bool BLI_path_abs(char *path, const char *basepath)
}
#ifdef WIN32
- /* skip first two chars, which in case of
- * absolute path will be drive:/blabla and
- * in case of relpath //blabla/. So relpath
- * // will be retained, rest will be nice and
- * shiny win32 backward slashes :) -jesterKing
- */
+ /* NOTE(@jesterking): Skip first two chars, which in case of absolute path will
+ * be `drive:/blabla` and in case of `relpath` `//blabla/`.
+ * So `relpath` `//` will be retained, rest will be nice and shiny WIN32 backward slashes. */
BLI_str_replace_char(path + 2, '/', '\\');
#endif
@@ -1897,7 +1894,7 @@ bool BLI_path_name_at_index(const char *__restrict path,
if (index_step == index) {
*r_offset = prev;
*r_len = i - prev;
- /* printf("!!! %d %d\n", start, end); */
+ // printf("!!! %d %d\n", start, end);
return true;
}
index_step += 1;
diff --git a/source/blender/blenlib/intern/polyfill_2d_beautify.c b/source/blender/blenlib/intern/polyfill_2d_beautify.c
index 7781e3a0f6f..ed07b002e32 100644
--- a/source/blender/blenlib/intern/polyfill_2d_beautify.c
+++ b/source/blender/blenlib/intern/polyfill_2d_beautify.c
@@ -25,7 +25,7 @@
* on a simple polygon representation where we _know_:
*
* - The polygon is primitive with no holes with a continuous boundary.
- * - Tris have consistent winding.
+ * - Triangles have consistent winding.
* - 2d (saves some hassles projecting face pairs on an axis for every edge-rotation)
* also saves us having to store all previous edge-states (see #EdRotState in bmesh_beautify.c)
*
diff --git a/source/blender/blenlib/intern/scanfill.c b/source/blender/blenlib/intern/scanfill.c
index b0d00007580..f0cf19bf508 100644
--- a/source/blender/blenlib/intern/scanfill.c
+++ b/source/blender/blenlib/intern/scanfill.c
@@ -430,7 +430,7 @@ static void testvertexnearedge(ScanFillContext *sf_ctx)
/* new edge */
ed1 = BLI_scanfill_edge_add(sf_ctx, eed->v1, eve);
- /* printf("fill: vertex near edge %x\n", eve); */
+ // printf("fill: vertex near edge %x\n", eve);
ed1->poly_nr = eed->poly_nr;
eed->v1 = eve;
eve->edge_tot = 3;
@@ -608,7 +608,7 @@ static unsigned int scanfill(ScanFillContext *sf_ctx, PolyFill *pf, const int fl
sc = scdata;
for (a = 0; a < verts; a++) {
- /* printf("VERTEX %d index %d\n", a, sc->vert->tmp.u); */
+ // printf("VERTEX %d index %d\n", a, sc->vert->tmp.u);
/* Set connect-flags. */
for (ed1 = sc->edge_first; ed1; ed1 = eed_next) {
eed_next = ed1->next;
@@ -634,13 +634,13 @@ static unsigned int scanfill(ScanFillContext *sf_ctx, PolyFill *pf, const int fl
* (and doesn't work during grab). */
/* if (callLocalInterruptCallBack()) break; */
if (totface >= maxface) {
- /* printf("Fill error: endless loop. Escaped at vert %d, tot: %d.\n", a, verts); */
+ // printf("Fill error: endless loop. Escaped at vert %d, tot: %d.\n", a, verts);
a = verts;
break;
}
if (ed2 == NULL) {
sc->edge_first = sc->edge_last = NULL;
- /* printf("just 1 edge to vert\n"); */
+ // printf("just 1 edge to vert\n");
BLI_addtail(&sf_ctx->filledgebase, ed1);
ed1->v2->f = SF_VERT_NEW;
ed1->v1->edge_tot--;
@@ -662,7 +662,7 @@ static unsigned int scanfill(ScanFillContext *sf_ctx, PolyFill *pf, const int fl
break;
}
- /* printf("test verts %d %d %d\n", v1->tmp.u, v2->tmp.u, v3->tmp.u); */
+ // printf("test verts %d %d %d\n", v1->tmp.u, v2->tmp.u, v3->tmp.u);
miny = min_ff(v1->xy[1], v3->xy[1]);
sc1 = sc + 1;
@@ -705,7 +705,7 @@ static unsigned int scanfill(ScanFillContext *sf_ctx, PolyFill *pf, const int fl
if (best_sc) {
/* make new edge, and start over */
- /* printf("add new edge %d %d and start again\n", v2->tmp.u, best_sc->vert->tmp.u); */
+ // printf("add new edge %d %d and start again\n", v2->tmp.u, best_sc->vert->tmp.u);
ed3 = BLI_scanfill_edge_add(sf_ctx, v2, best_sc->vert);
BLI_remlink(&sf_ctx->filledgebase, ed3);
@@ -717,7 +717,7 @@ static unsigned int scanfill(ScanFillContext *sf_ctx, PolyFill *pf, const int fl
}
else {
/* new triangle */
- /* printf("add face %d %d %d\n", v1->tmp.u, v2->tmp.u, v3->tmp.u); */
+ // printf("add face %d %d %d\n", v1->tmp.u, v2->tmp.u, v3->tmp.u);
addfillface(sf_ctx, v1, v2, v3);
totface++;
BLI_remlink((ListBase *)&(sc->edge_first), ed1);
@@ -741,11 +741,11 @@ static unsigned int scanfill(ScanFillContext *sf_ctx, PolyFill *pf, const int fl
ed3->v1->edge_tot++;
ed3->v2->edge_tot++;
- /* printf("add new edge %x %x\n", v1, v3); */
+ // printf("add new edge %x %x\n", v1, v3);
sc1 = addedgetoscanlist(scdata, ed3, verts);
if (sc1) { /* ed3 already exists: remove if a boundary */
- /* printf("Edge exists\n"); */
+ // printf("Edge exists\n");
ed3->v1->edge_tot--;
ed3->v2->edge_tot--;
@@ -954,7 +954,7 @@ unsigned int BLI_scanfill_calc_ex(ScanFillContext *sf_ctx, const int flag, const
poly++;
}
}
- /* printf("amount of poly's: %d\n", poly); */
+ // printf("amount of poly's: %d\n", poly);
}
else if (poly) {
/* we pre-calculated poly_nr */
@@ -1020,7 +1020,7 @@ unsigned int BLI_scanfill_calc_ex(ScanFillContext *sf_ctx, const int flag, const
}
}
if (BLI_listbase_is_empty(&sf_ctx->filledgebase)) {
- /* printf("All edges removed\n"); */
+ // printf("All edges removed\n");
return 0;
}
}
diff --git a/source/blender/blenlib/intern/storage.c b/source/blender/blenlib/intern/storage.c
index 19b925535e2..47bb2f0e8dd 100644
--- a/source/blender/blenlib/intern/storage.c
+++ b/source/blender/blenlib/intern/storage.c
@@ -114,7 +114,7 @@ double BLI_dir_free_space(const char *dir)
tmp[0] = '\\';
tmp[1] = 0; /* Just a fail-safe. */
- if (ELEM(dir[0] == '/', '\\')) {
+ if (ELEM(dir[0], '/', '\\')) {
tmp[0] = '\\';
tmp[1] = 0;
}