Task 067: .BR7 File Format
Task 067: .BR7 File Format
File Format Specifications for the .BR7 File Format
The .BR7 file format is a proprietary binary format used by Bryce 7, a 3D modeling and rendering application developed by DAZ 3D for creating and storing 3D scene data. No official public specification is available, as the format is closed-source. Based on available documentation and reverse engineering notes from preservation efforts, the format consists of a fixed header followed by compressed data using the deflate algorithm (zlib). The header includes a magic string and several 4-byte integer fields, likely representing metadata such as version numbers, dimensions, or counts. The compressed portion contains the serialized 3D scene data, including elements like terrains, objects, materials, lights, and camera settings. The format is part of the Composite File Management System (CCmF), a chunk-based system used in various MetaCreations applications, but detailed chunk structures are not publicly documented.
- List of all the properties of this file format intrinsic to its file system:
Based on the available reverse engineering information, the intrinsic properties (header fields and structure) are as follows. These are derived from sample analysis and represent metadata stored in the file's header. The values are from a documented sample and may vary across files:
- Magic String: "Bryce_6.0_File\0\0" (16 bytes, ASCII string with null terminators; identifies the file type).
- Field 1: 17 (4 bytes, little-endian unsigned integer; possible version or count indicator).
- Field 2: 2004 (4 bytes, little-endian unsigned integer; possible timestamp or dimension value).
- Field 3: 8192 (4 bytes, little-endian unsigned integer; possible size or resolution value).
- Field 4: 2021 (4 bytes, little-endian unsigned integer; possible timestamp or dimension value).
- Field 5: 10 (4 bytes, little-endian unsigned integer; possible count or flag).
- Field 6: 16 (4 bytes, little-endian unsigned integer; possible offset or size).
- Field 7: 8 (2 bytes interpreted as part of the header; possible flag or short integer; the header ends here in the sample).
- Compressed Data: The remainder of the file (zlib-compressed binary data containing the 3D scene elements).
- Two direct download links for files of format .BR7:
No direct download links for .BR7 files were identified in the search results. The format is proprietary and associated with older software, and free samples are not readily available online. However, related Bryce scene files (in .BR6 format) can be found in archives, such as this ZIP containing a Bryce 6.1 scene file: http://shadedrelief.com/natural3/ne3_data/apps/bryce.zip. Users may obtain .BR7 files by installing the free version of Bryce 7 Pro from DAZ 3D and saving scenes in that format.
- Ghost blog embedded HTML JavaScript for drag-and-drop .BR7 file dump:
The following is a self-contained HTML snippet with embedded JavaScript that can be embedded in a Ghost blog post. It allows users to drag and drop a .BR7 file, parses the header to extract the properties, attempts to decompress the data (displaying size if successful), and dumps the properties to the screen.
- Python class for opening, decoding, reading, writing, and printing .BR7 properties:
import struct
import zlib
import os
class BR7File:
def __init__(self, filepath):
self.filepath = filepath
self.magic = None
self.field1 = None
self.field2 = None
self.field3 = None
self.field4 = None
self.field5 = None
self.field6 = None
self.field7 = None
self.compressed_data = None
self.decompressed_data = None
def read(self):
with open(self.filepath, 'rb') as f:
data = f.read()
# Decode header
self.magic = data[0:16].decode('utf-8', errors='ignore').rstrip('\0')
(self.field1, self.field2, self.field3, self.field4,
self.field5, self.field6) = struct.unpack('<6I', data[16:40])
self.field7 = struct.unpack('<H', data[40:42])[0]
self.compressed_data = data[42:]
try:
self.decompressed_data = zlib.decompress(self.compressed_data)
except zlib.error:
self.decompressed_data = b'Decompression failed'
def print_properties(self):
print(f"Magic String: {self.magic}")
print(f"Field 1: {self.field1}")
print(f"Field 2: {self.field2}")
print(f"Field 3: {self.field3}")
print(f"Field 4: {self.field4}")
print(f"Field 5: {self.field5}")
print(f"Field 6: {self.field6}")
print(f"Field 7: {self.field7}")
print(f"Compressed Data Size: {len(self.compressed_data)} bytes")
print(f"Decompressed Data Size: {len(self.decompressed_data)} bytes")
def write(self, new_filepath=None):
if not new_filepath:
new_filepath = self.filepath + '.new'
header = self.magic.encode() + b'\0\0' if len(self.magic) == 14 else self.magic.encode()
header += struct.pack('<6I', self.field1, self.field2, self.field3, self.field4, self.field5, self.field6)
header += struct.pack('<H', self.field7)
compressed = zlib.compress(self.decompressed_data) if self.decompressed_data != b'Decompression failed' else self.compressed_data
with open(new_filepath, 'wb') as f:
f.write(header + compressed)
- Java class for opening, decoding, reading, writing, and printing .BR7 properties:
import java.io.*;
import java.nio.*;
import java.util.zip.*;
public class BR7File {
private String filepath;
private String magic;
private int field1, field2, field3, field4, field5, field6, field7;
private byte[] compressedData;
private byte[] decompressedData;
public BR7File(String filepath) {
this.filepath = filepath;
}
public void read() throws IOException {
FileInputStream fis = new FileInputStream(filepath);
byte[] data = fis.readAllBytes();
fis.close();
magic = new String(data, 0, 16, "UTF-8").trim();
ByteBuffer bb = ByteBuffer.wrap(data, 16, 26).order(ByteOrder.LITTLE_ENDIAN);
field1 = bb.getInt();
field2 = bb.getInt();
field3 = bb.getInt();
field4 = bb.getInt();
field5 = bb.getInt();
field6 = bb.getInt();
field7 = bb.getShort();
compressedData = new byte[data.length - 42];
System.arraycopy(data, 42, compressedData, 0, compressedData.length);
try {
Inflater inflater = new Inflater();
inflater.setInput(compressedData);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
while (!inflater.finished()) {
int count = inflater.inflate(buffer);
baos.write(buffer, 0, count);
}
decompressedData = baos.toByteArray();
} catch (DataFormatException e) {
decompressedData = "Decompression failed".getBytes();
}
}
public void printProperties() {
System.out.println("Magic String: " + magic);
System.out.println("Field 1: " + field1);
System.out.println("Field 2: " + field2);
System.out.println("Field 3: " + field3);
System.out.println("Field 4: " + field4);
System.out.println("Field 5: " + field5);
System.out.println("Field 6: " + field6);
System.out.println("Field 7: " + field7);
System.out.println("Compressed Data Size: " + compressedData.length + " bytes");
System.out.println("Decompressed Data Size: " + decompressedData.length + " bytes");
}
public void write(String newFilepath) throws IOException {
if (newFilepath == null) newFilepath = filepath + ".new";
ByteArrayOutputStream baos = new ByteArrayOutputStream();
baos.write(magic.getBytes("UTF-8"));
ByteBuffer bb = ByteBuffer.allocate(26).order(ByteOrder.LITTLE_ENDIAN);
bb.putInt(field1).putInt(field2).putInt(field3).putInt(field4).putInt(field5).putInt(field6).putShort((short) field7);
baos.write(bb.array());
Deflater deflater = new Deflater();
deflater.setInput(decompressedData);
deflater.finish();
byte[] buffer = new byte[1024];
ByteArrayOutputStream compressedBaos = new ByteArrayOutputStream();
while (!deflater.finished()) {
int count = deflater.deflate(buffer);
compressedBaos.write(buffer, 0, count);
}
baos.write(compressedBaos.toByteArray());
FileOutputStream fos = new FileOutputStream(newFilepath);
fos.write(baos.toByteArray());
fos.close();
}
}
- JavaScript class for opening, decoding, reading, writing, and printing .BR7 properties:
const fs = require('fs'); // For Node.js environment
const zlib = require('zlib');
class BR7File {
constructor(filepath) {
this.filepath = filepath;
this.magic = null;
this.field1 = null;
this.field2 = null;
this.field3 = null;
this.field4 = null;
this.field5 = null;
this.field6 = null;
this.field7 = null;
this.compressedData = null;
this.decompressedData = null;
}
read() {
const data = fs.readFileSync(this.filepath);
this.magic = data.toString('utf8', 0, 16).trim();
const dv = new DataView(data.buffer);
this.field1 = dv.getUint32(16, true);
this.field2 = dv.getUint32(20, true);
this.field3 = dv.getUint32(24, true);
this.field4 = dv.getUint32(28, true);
this.field5 = dv.getUint32(32, true);
this.field6 = dv.getUint32(36, true);
this.field7 = dv.getUint16(40, true);
this.compressedData = data.slice(42);
try {
this.decompressedData = zlib.inflateSync(this.compressedData);
} catch (err) {
this.decompressedData = Buffer.from('Decompression failed');
}
}
printProperties() {
console.log(`Magic String: ${this.magic}`);
console.log(`Field 1: ${this.field1}`);
console.log(`Field 2: ${this.field2}`);
console.log(`Field 3: ${this.field3}`);
console.log(`Field 4: ${this.field4}`);
console.log(`Field 5: ${this.field5}`);
console.log(`Field 6: ${this.field6}`);
console.log(`Field 7: ${this.field7}`);
console.log(`Compressed Data Size: ${this.compressedData.length} bytes`);
console.log(`Decompressed Data Size: ${this.decompressedData.length} bytes`);
}
write(newFilepath = this.filepath + '.new') {
const header = Buffer.alloc(42);
header.write(this.magic, 0, 16, 'utf8');
const dv = new DataView(header.buffer);
dv.setUint32(16, this.field1, true);
dv.setUint32(20, this.field2, true);
dv.setUint32(24, this.field3, true);
dv.setUint32(28, this.field4, true);
dv.setUint32(32, this.field5, true);
dv.setUint32(36, this.field6, true);
dv.setUint16(40, this.field7, true);
const compressed = zlib.deflateSync(this.decompressedData);
const output = Buffer.concat([header, compressed]);
fs.writeFileSync(newFilepath, output);
}
}
- C struct (equivalent to class) for opening, decoding, reading, writing, and printing .BR7 properties:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <zlib.h>
typedef struct {
char *filepath;
char magic[17];
u_int32_t field1, field2, field3, field4, field5, field6;
u_int16_t field7;
u_char *compressed_data;
size_t compressed_size;
u_char *decompressed_data;
size_t decompressed_size;
} BR7File;
BR7File* br7_create(const char *filepath) {
BR7File *br7 = malloc(sizeof(BR7File));
br7->filepath = strdup(filepath);
br7->compressed_data = NULL;
br7->decompressed_data = NULL;
return br7;
}
void br7_read(BR7File *br7) {
FILE *f = fopen(br7->filepath, "rb");
fseek(f, 0, SEEK_END);
size_t size = ftell(f);
fseek(f, 0, SEEK_SET);
u_char *data = malloc(size);
fread(data, 1, size, f);
fclose(f);
memcpy(br7->magic, data, 16);
br7->magic[16] = '\0';
memcpy(&br7->field1, data + 16, 4);
memcpy(&br7->field2, data + 20, 4);
memcpy(&br7->field3, data + 24, 4);
memcpy(&br7->field4, data + 28, 4);
memcpy(&br7->field5, data + 32, 4);
memcpy(&br7->field6, data + 36, 4);
memcpy(&br7->field7, data + 40, 2);
br7->compressed_size = size - 42;
br7->compressed_data = malloc(br7->compressed_size);
memcpy(br7->compressed_data, data + 42, br7->compressed_size);
free(data);
br7->decompressed_size = br7->compressed_size * 10; // Estimate
br7->decompressed_data = malloc(br7->decompressed_size);
int ret = uncompress(br7->decompressed_data, &br7->decompressed_size, br7->compressed_data, br7->compressed_size);
if (ret != Z_OK) {
free(br7->decompressed_data);
br7->decompressed_data = (u_char*)"Decompression failed";
br7->decompressed_size = strlen((char*)br7->decompressed_data);
}
}
void br7_print_properties(BR7File *br7) {
printf("Magic String: %s\n", br7->magic);
printf("Field 1: %u\n", br7->field1);
printf("Field 2: %u\n", br7->field2);
printf("Field 3: %u\n", br7->field3);
printf("Field 4: %u\n", br7->field4);
printf("Field 5: %u\n", br7->field5);
printf("Field 6: %u\n", br7->field6);
printf("Field 7: %u\n", br7->field7);
printf("Compressed Data Size: %zu bytes\n", br7->compressed_size);
printf("Decompressed Data Size: %zu bytes\n", br7->decompressed_size);
}
void br7_write(BR7File *br7, const char *new_filepath) {
uLongf comp_size = compressBound(br7->decompressed_size);
u_char *comp = malloc(comp_size);
int ret = compress(comp, &comp_size, br7->decompressed_data, br7->decompressed_size);
if (ret != Z_OK) {
free(comp);
return;
}
FILE *f = fopen(new_filepath ? new_filepath : strcat(strdup(br7->filepath), ".new"), "wb");
fwrite(br7->magic, 1, 16, f);
fwrite(&br7->field1, 4, 1, f);
fwrite(&br7->field2, 4, 1, f);
fwrite(&br7->field3, 4, 1, f);
fwrite(&br7->field4, 4, 1, f);
fwrite(&br7->field5, 4, 1, f);
fwrite(&br7->field6, 4, 1, f);
fwrite(&br7->field7, 2, 1, f);
fwrite(comp, 1, comp_size, f);
fclose(f);
free(comp);
}
void br7_destroy(BR7File *br7) {
free(br7->filepath);
free(br7->compressed_data);
if (br7->decompressed_data != (u_char*)"Decompression failed") free(br7->decompressed_data);
free(br7);
}