Пример #1
0
void BLI_endian_switch_int32_array(int *val, const int size)
{
	if (size > 0) {
		int i = size;
		val = val + (size - 1);
		while (i--) {
			BLI_endian_switch_int32(val--);
		}
	}
}
Пример #2
0
struct anim_index *IMB_indexer_open(const char *name)
{
	char header[13];
	struct anim_index *idx;
	FILE *fp = BLI_fopen(name, "rb");
	int i;

	if (!fp) {
		return NULL;
	}

	if (fread(header, 12, 1, fp) != 1) {
		fclose(fp);
		return NULL;
	}

	header[12] = 0;

	if (memcmp(header, magic, 8) != 0) {
		fclose(fp);
		return NULL;
	}

	if (atoi(header + 9) != INDEX_FILE_VERSION) {
		fclose(fp);
		return NULL;
	}

	idx = MEM_callocN(sizeof(struct anim_index), "anim_index");

	BLI_strncpy(idx->name, name, sizeof(idx->name));
	
	fseek(fp, 0, SEEK_END);

	idx->num_entries = (ftell(fp) - 12) /
	                   (sizeof(int) +                /* framepos */
	                    sizeof(unsigned long long) + /* seek_pos */
	                    sizeof(unsigned long long) + /* seek_pos_dts */
	                    sizeof(unsigned long long)   /* pts */
	                   );

	fseek(fp, 12, SEEK_SET);

	idx->entries = MEM_callocN(sizeof(struct anim_index_entry) *
	                           idx->num_entries, "anim_index_entries");

	for (i = 0; i < idx->num_entries; i++) {
		fread(&idx->entries[i].frameno,
		      sizeof(int), 1, fp);
		fread(&idx->entries[i].seek_pos,
		      sizeof(unsigned long long), 1, fp);
		fread(&idx->entries[i].seek_pos_dts,
		      sizeof(unsigned long long), 1, fp);
		fread(&idx->entries[i].pts,
		      sizeof(unsigned long long), 1, fp);
	}

	if (((ENDIAN_ORDER == B_ENDIAN) != (header[8] == 'V'))) {
		for (i = 0; i < idx->num_entries; i++) {
			BLI_endian_switch_int32(&idx->entries[i].frameno);
			BLI_endian_switch_int64((int64_t *)&idx->entries[i].seek_pos);
			BLI_endian_switch_int64((int64_t *)&idx->entries[i].seek_pos_dts);
			BLI_endian_switch_int64((int64_t *)&idx->entries[i].pts);
		}
	}

	fclose(fp);

	return idx;
}
Пример #3
0
/**
 * In sdna->data the data, now we convert that to something understandable
 */
static bool init_structDNA(
        SDNA *sdna, bool do_endian_swap,
        const char **r_error_message)
{
	int *data, *verg, gravity_fix = -1;
	short *sp;
	char str[8];
	
	verg = (int *)str;
	data = (int *)sdna->data;

	/* clear pointers incase of error */
	sdna->names = NULL;
	sdna->types = NULL;
	sdna->structs = NULL;
#ifdef WITH_DNA_GHASH
	sdna->structs_map = NULL;
#endif

	strcpy(str, "SDNA");
	if (*data != *verg) {
		*r_error_message = "SDNA error in SDNA file";
		return false;
	}
	else {
		const char *cp;

		data++;
		
		/* load names array */
		strcpy(str, "NAME");
		if (*data == *verg) {
			data++;
			
			sdna->nr_names = *data;
			if (do_endian_swap) {
				BLI_endian_switch_int32(&sdna->nr_names);
			}
			
			data++;
			sdna->names = MEM_callocN(sizeof(void *) * sdna->nr_names, "sdnanames");
		}
		else {
			*r_error_message = "NAME error in SDNA file";
			return false;
		}
		
		cp = (char *)data;
		for (int nr = 0; nr < sdna->nr_names; nr++) {
			sdna->names[nr] = cp;

			/* "float gravity [3]" was parsed wrong giving both "gravity" and
			 * "[3]"  members. we rename "[3]", and later set the type of
			 * "gravity" to "void" so the offsets work out correct */
			if (*cp == '[' && strcmp(cp, "[3]") == 0) {
				if (nr && strcmp(sdna->names[nr - 1], "Cvi") == 0) {
					sdna->names[nr] = "gravity[3]";
					gravity_fix = nr;
				}
			}

			while (*cp) cp++;
			cp++;
		}

		cp = pad_up_4(cp);
		
		/* load type names array */
		data = (int *)cp;
		strcpy(str, "TYPE");
		if (*data == *verg) {
			data++;

			sdna->nr_types = *data;
			if (do_endian_swap) {
				BLI_endian_switch_int32(&sdna->nr_types);
			}
			
			data++;
			sdna->types = MEM_callocN(sizeof(void *) * sdna->nr_types, "sdnatypes");
		}
		else {
			*r_error_message = "TYPE error in SDNA file";
			return false;
		}
		
		cp = (char *)data;
		for (int nr = 0; nr < sdna->nr_types; nr++) {
			sdna->types[nr] = cp;
			
			/* this is a patch, to change struct names without a conflict with SDNA */
			/* be careful to use it, in this case for a system-struct (opengl/X) */
			
			if (*cp == 'b') {
				/* struct Screen was already used by X, 'bScreen' replaces the old IrisGL 'Screen' struct */
				if (strcmp("bScreen", cp) == 0) sdna->types[nr] = cp + 1;
			}
			
			while (*cp) cp++;
			cp++;
		}

		cp = pad_up_4(cp);
		
		/* load typelen array */
		data = (int *)cp;
		strcpy(str, "TLEN");
		if (*data == *verg) {
			data++;
			sp = (short *)data;
			sdna->typelens = sp;
			
			if (do_endian_swap) {
				BLI_endian_switch_int16_array(sp, sdna->nr_types);
			}
			
			sp += sdna->nr_types;
		}
		else {
			*r_error_message = "TLEN error in SDNA file";
			return false;
		}
		if (sdna->nr_types & 1) sp++;   /* prevent BUS error */

		/* load struct array */
		data = (int *)sp;
		strcpy(str, "STRC");
		if (*data == *verg) {
			data++;
			
			sdna->nr_structs = *data;
			if (do_endian_swap) {
				BLI_endian_switch_int32(&sdna->nr_structs);
			}
			
			data++;
			sdna->structs = MEM_callocN(sizeof(void *) * sdna->nr_structs, "sdnastrcs");
		}
		else {
			*r_error_message = "STRC error in SDNA file";
			return false;
		}
		
		sp = (short *)data;
		for (int nr = 0; nr < sdna->nr_structs; nr++) {
			sdna->structs[nr] = sp;
			
			if (do_endian_swap) {
				short a;
				
				BLI_endian_switch_int16(&sp[0]);
				BLI_endian_switch_int16(&sp[1]);
				
				a = sp[1];
				sp += 2;
				while (a--) {
					BLI_endian_switch_int16(&sp[0]);
					BLI_endian_switch_int16(&sp[1]);
					sp += 2;
				}
			}
			else {
				sp += 2 * sp[1] + 2;
			}
		}
	}

	{
		/* second part of gravity problem, setting "gravity" type to void */
		if (gravity_fix > -1) {
			for (int nr = 0; nr < sdna->nr_structs; nr++) {
				sp = sdna->structs[nr];
				if (strcmp(sdna->types[sp[0]], "ClothSimSettings") == 0)
					sp[10] = SDNA_TYPE_VOID;
			}
		}
	}

#ifdef WITH_DNA_GHASH
	{
		/* create a ghash lookup to speed up */
		sdna->structs_map = BLI_ghash_str_new_ex("init_structDNA gh", sdna->nr_structs);

		for (intptr_t nr = 0; nr < sdna->nr_structs; nr++) {
			sp = sdna->structs[nr];
			BLI_ghash_insert(sdna->structs_map, (void *)sdna->types[sp[0]], SET_INT_IN_POINTER(nr));
		}
	}
#endif

	/* Calculate 'sdna->pointerlen' */
	{
		intptr_t nr = DNA_struct_find_nr(sdna, "ListBase");

		/* should never happen, only with corrupt file for example */
		if (UNLIKELY(nr == -1)) {
			*r_error_message = "ListBase struct error! Not found.";
			return false;
		}

		/* finally pointerlen: use struct ListBase to test it, never change the size of it! */
		sp = sdna->structs[nr];
		/* weird; i have no memory of that... I think I used sizeof(void *) before... (ton) */

		sdna->pointerlen = sdna->typelens[sp[0]] / 2;

		if (sp[1] != 2 || (sdna->pointerlen != 4 && sdna->pointerlen != 8)) {
			*r_error_message = "ListBase struct error! Needs it to calculate pointerize.";
			/* well, at least sizeof(ListBase) is error proof! (ton) */
			return false;
		}
	}

	return true;
}