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:
authorBrecht Van Lommel <brechtvanlommel@pandora.be>2009-12-10 17:26:06 +0300
committerBrecht Van Lommel <brechtvanlommel@pandora.be>2009-12-10 17:26:06 +0300
commitacadb8c39f83a4b4112c8c77bac1eb39584ad100 (patch)
tree6e6249a3b1a8ef81bf74efb4dacfb2be8fa37c24 /source/blender/blenkernel/intern/customdata_file.c
parent6639ba6b867581ece49423f2c92651727fd4552f (diff)
Sculpt Branch:
Revised external multires file saving. Now it is more manual in that you have to specify where to save it, like an image file, but still saved at the same time as the .blend. It would ideally be automatic, but this is difficult to implement, so for now this should at least be more reliable.
Diffstat (limited to 'source/blender/blenkernel/intern/customdata_file.c')
-rw-r--r--source/blender/blenkernel/intern/customdata_file.c446
1 files changed, 446 insertions, 0 deletions
diff --git a/source/blender/blenkernel/intern/customdata_file.c b/source/blender/blenkernel/intern/customdata_file.c
new file mode 100644
index 00000000000..b58ada878de
--- /dev/null
+++ b/source/blender/blenkernel/intern/customdata_file.c
@@ -0,0 +1,446 @@
+/*
+ * $Id$
+ *
+ * ***** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_fileops.h"
+#include "BLI_string.h"
+
+#include "BKE_customdata_file.h"
+#include "BKE_global.h"
+#include "BKE_utildefines.h"
+
+/************************* File Format Definitions ***************************/
+
+#define CDF_ENDIAN_LITTLE 0
+#define CDF_ENDIAN_BIG 1
+
+#define CDF_DATA_FLOAT 0
+
+typedef struct CDataFileHeader {
+ char ID[4]; /* "BCDF" */
+ char endian; /* little, big */
+ char version; /* non-compatible versions */
+ char subversion; /* compatible sub versions */
+ char pad; /* padding */
+
+ int structbytes; /* size of this struct in bytes */
+ int type; /* image, mesh */
+ int totlayer; /* number of layers in the file */
+} CDataFileHeader;
+
+typedef struct CDataFileImageHeader {
+ int structbytes; /* size of this struct in bytes */
+ int width; /* image width */
+ int height; /* image height */
+ int tile_size; /* tile size (required power of 2) */
+} CDataFileImageHeader;
+
+typedef struct CDataFileMeshHeader {
+ int structbytes; /* size of this struct in bytes */
+} CDataFileMeshHeader;
+
+struct CDataFileLayer {
+ int structbytes; /* size of this struct in bytes */
+ int datatype; /* only float for now */
+ uint64_t datasize; /* size of data in layer */
+ int type; /* layer type */
+ char name[CDF_LAYER_NAME_MAX]; /* layer name */
+};
+
+/**************************** Other Definitions ******************************/
+
+#define CDF_VERSION 0
+#define CDF_SUBVERSION 0
+#define CDF_TILE_SIZE 64
+
+struct CDataFile {
+ int type;
+
+ CDataFileHeader header;
+ union {
+ CDataFileImageHeader image;
+ CDataFileMeshHeader mesh;
+ } btype;
+
+ CDataFileLayer *layer;
+ int totlayer;
+
+ FILE *readf;
+ FILE *writef;
+ int switchendian;
+ size_t dataoffset;
+};
+
+/********************************* Create/Free *******************************/
+
+static int cdf_endian(void)
+{
+ if(ENDIAN_ORDER == L_ENDIAN)
+ return CDF_ENDIAN_LITTLE;
+ else
+ return CDF_ENDIAN_BIG;
+}
+
+/*static int cdf_data_type_size(int datatype)
+{
+ if(datatype == CDF_DATA_FLOAT)
+ return sizeof(float);
+
+ return 0;
+}*/
+
+CDataFile *cdf_create(int type)
+{
+ CDataFile *cdf= MEM_callocN(sizeof(CDataFile), "CDataFile");
+
+ cdf->type= type;
+
+ return cdf;
+}
+
+void cdf_free(CDataFile *cdf)
+{
+ cdf_read_close(cdf);
+ cdf_write_close(cdf);
+
+ if(cdf->layer)
+ MEM_freeN(cdf->layer);
+
+ MEM_freeN(cdf);
+}
+
+/********************************* Read/Write ********************************/
+
+static int cdf_read_header(CDataFile *cdf)
+{
+ CDataFileHeader *header;
+ CDataFileImageHeader *image;
+ CDataFileMeshHeader *mesh;
+ CDataFileLayer *layer;
+ FILE *f= cdf->readf;
+ size_t offset = 0;
+ int a;
+
+ header= &cdf->header;
+
+ if(!fread(header, sizeof(CDataFileHeader), 1, cdf->readf))
+ return 0;
+
+ if(memcmp(header->ID, "BCDF", sizeof(header->ID)) != 0)
+ return 0;
+ if(header->version > CDF_VERSION)
+ return 0;
+
+ cdf->switchendian= header->endian != cdf_endian();
+ header->endian= cdf_endian();
+
+ if(cdf->switchendian) {
+ SWITCH_INT(header->type);
+ SWITCH_INT(header->totlayer);
+ SWITCH_INT(header->structbytes);
+ }
+
+ if(!ELEM(header->type, CDF_TYPE_IMAGE, CDF_TYPE_MESH))
+ return 0;
+
+ offset += header->structbytes;
+ header->structbytes= sizeof(CDataFileHeader);
+
+ if(fseek(f, offset, SEEK_SET) != 0)
+ return 0;
+
+ if(header->type == CDF_TYPE_IMAGE) {
+ image= &cdf->btype.image;
+ if(!fread(image, sizeof(CDataFileImageHeader), 1, f))
+ return 0;
+
+ if(cdf->switchendian) {
+ SWITCH_INT(image->width);
+ SWITCH_INT(image->height);
+ SWITCH_INT(image->tile_size);
+ SWITCH_INT(image->structbytes);
+ }
+
+ offset += image->structbytes;
+ image->structbytes= sizeof(CDataFileImageHeader);
+ }
+ else if(header->type == CDF_TYPE_MESH) {
+ mesh= &cdf->btype.mesh;
+ if(!fread(mesh, sizeof(CDataFileMeshHeader), 1, f))
+ return 0;
+
+ if(cdf->switchendian)
+ SWITCH_INT(mesh->structbytes);
+
+ offset += mesh->structbytes;
+ mesh->structbytes= sizeof(CDataFileMeshHeader);
+ }
+
+ if(fseek(f, offset, SEEK_SET) != 0)
+ return 0;
+
+ cdf->layer= MEM_callocN(sizeof(CDataFileLayer)*header->totlayer, "CDataFileLayer");
+ cdf->totlayer= header->totlayer;
+
+ for(a=0; a<header->totlayer; a++) {
+ layer= &cdf->layer[a];
+
+ if(!fread(layer, sizeof(CDataFileLayer), 1, f))
+ return 0;
+
+ if(cdf->switchendian) {
+ SWITCH_INT(layer->type);
+ SWITCH_INT(layer->datatype);
+ SWITCH_INT64(layer->datasize);
+ SWITCH_INT(layer->structbytes);
+ }
+
+ if(layer->datatype != CDF_DATA_FLOAT)
+ return 0;
+
+ offset += layer->structbytes;
+ layer->structbytes= sizeof(CDataFileLayer);
+
+ if(fseek(f, offset, SEEK_SET) != 0)
+ return 0;
+ }
+
+ cdf->dataoffset= offset;
+
+ return 1;
+}
+
+static int cdf_write_header(CDataFile *cdf)
+{
+ CDataFileHeader *header;
+ CDataFileImageHeader *image;
+ CDataFileMeshHeader *mesh;
+ CDataFileLayer *layer;
+ FILE *f= cdf->writef;
+ int a;
+
+ header= &cdf->header;
+
+ if(!fwrite(header, sizeof(CDataFileHeader), 1, f))
+ return 0;
+
+ if(header->type == CDF_TYPE_IMAGE) {
+ image= &cdf->btype.image;
+ if(!fwrite(image, sizeof(CDataFileImageHeader), 1, f))
+ return 0;
+ }
+ else if(header->type == CDF_TYPE_MESH) {
+ mesh= &cdf->btype.mesh;
+ if(!fwrite(mesh, sizeof(CDataFileMeshHeader), 1, f))
+ return 0;
+ }
+
+ for(a=0; a<header->totlayer; a++) {
+ layer= &cdf->layer[a];
+
+ if(!fwrite(layer, sizeof(CDataFileLayer), 1, f))
+ return 0;
+ }
+
+ return 1;
+}
+
+int cdf_read_open(CDataFile *cdf, char *filename)
+{
+ FILE *f;
+
+ f= fopen(filename, "rb");
+ if(!f)
+ return 0;
+
+ cdf->readf= f;
+
+ if(!cdf_read_header(cdf)) {
+ cdf_read_close(cdf);
+ return 0;
+ }
+
+ if(cdf->header.type != cdf->type) {
+ cdf_read_close(cdf);
+ return 0;
+ }
+
+ return 1;
+}
+
+int cdf_read_layer(CDataFile *cdf, CDataFileLayer *blay)
+{
+ size_t offset;
+ int a;
+
+ /* seek to right location in file */
+ offset= cdf->dataoffset;
+ for(a=0; a<cdf->totlayer; a++) {
+ if(&cdf->layer[a] == blay)
+ break;
+ else
+ offset += cdf->layer[a].datasize;
+ }
+
+ return (fseek(cdf->readf, offset, SEEK_SET) == 0);
+}
+
+int cdf_read_data(CDataFile *cdf, int size, void *data)
+{
+ float *fdata;
+ int a;
+
+ /* read data */
+ if(!fread(data, size, 1, cdf->readf))
+ return 0;
+
+ /* switch endian if necessary */
+ if(cdf->switchendian) {
+ fdata= data;
+
+ for(a=0; a<size/sizeof(float); a++)
+ SWITCH_INT(fdata[a])
+ }
+
+ return 1;
+}
+
+void cdf_read_close(CDataFile *cdf)
+{
+ if(cdf->readf) {
+ fclose(cdf->readf);
+ cdf->readf= NULL;
+ }
+}
+
+int cdf_write_open(CDataFile *cdf, char *filename)
+{
+ CDataFileHeader *header;
+ CDataFileImageHeader *image;
+ CDataFileMeshHeader *mesh;
+ FILE *f;
+
+ f= fopen(filename, "wb");
+ if(!f)
+ return 0;
+
+ cdf->writef= f;
+
+ /* fill header */
+ header= &cdf->header;
+ strcpy(header->ID, "BCDF");
+ header->endian= cdf_endian();
+ header->version= CDF_VERSION;
+ header->subversion= CDF_SUBVERSION;
+
+ header->structbytes= sizeof(CDataFileHeader);
+ header->type= cdf->type;
+ header->totlayer= cdf->totlayer;
+
+ if(cdf->type == CDF_TYPE_IMAGE) {
+ /* fill image header */
+ image= &cdf->btype.image;
+ image->structbytes= sizeof(CDataFileImageHeader);
+ image->tile_size= CDF_TILE_SIZE;
+ }
+ else if(cdf->type == CDF_TYPE_MESH) {
+ /* fill mesh header */
+ mesh= &cdf->btype.mesh;
+ mesh->structbytes= sizeof(CDataFileMeshHeader);
+ }
+
+ cdf_write_header(cdf);
+
+ return 1;
+}
+
+int cdf_write_layer(CDataFile *cdf, CDataFileLayer *blay)
+{
+ return 1;
+}
+
+int cdf_write_data(CDataFile *cdf, int size, void *data)
+{
+ /* write data */
+ if(!fwrite(data, size, 1, cdf->writef))
+ return 0;
+
+ return 1;
+}
+
+void cdf_write_close(CDataFile *cdf)
+{
+ if(cdf->writef) {
+ fclose(cdf->writef);
+ cdf->writef= NULL;
+ }
+}
+
+void cdf_remove(char *filename)
+{
+ BLI_delete(filename, 0, 0);
+}
+
+/********************************** Layers ***********************************/
+
+CDataFileLayer *cdf_layer_find(CDataFile *cdf, int type, char *name)
+{
+ CDataFileLayer *layer;
+ int a;
+
+ for(a=0; a<cdf->totlayer; a++) {
+ layer= &cdf->layer[a];
+
+ if(layer->type == type && strcmp(layer->name, name) == 0)
+ return layer;
+ }
+
+ return NULL;
+}
+
+CDataFileLayer *cdf_layer_add(CDataFile *cdf, int type, char *name, size_t datasize)
+{
+ CDataFileLayer *newlayer, *layer;
+
+ /* expand array */
+ newlayer= MEM_callocN(sizeof(CDataFileLayer)*(cdf->totlayer+1), "CDataFileLayer");
+ memcpy(newlayer, cdf->layer, sizeof(CDataFileLayer)*cdf->totlayer);
+ cdf->layer= newlayer;
+
+ cdf->totlayer++;
+
+ /* fill in new layer */
+ layer= &cdf->layer[cdf->totlayer-1];
+ layer->structbytes= sizeof(CDataFileLayer);
+ layer->datatype= CDF_DATA_FLOAT;
+ layer->datasize= datasize;
+ layer->type= type;
+ BLI_strncpy(layer->name, name, CDF_LAYER_NAME_MAX);
+
+ return layer;
+}
+