Skip to content

Commit

Permalink
Initial metadata implementation
Browse files Browse the repository at this point in the history
Fix various spec issues.

Affects #12
  • Loading branch information
io7m committed Nov 29, 2016
1 parent e91f6b3 commit ca4826d
Show file tree
Hide file tree
Showing 32 changed files with 1,364 additions and 269 deletions.
18 changes: 18 additions & 0 deletions io7m-smfj-cmdline/src/main/java/com/io7m/smfj/cmdline/Main.java
Expand Up @@ -558,6 +558,24 @@ public void onDataTrianglesFinish()
{

}

@Override
public boolean onMeta(
final int vendor,
final int schema,
final long length)
{
return true;
}

@Override
public void onMetaData(
final int vendor,
final int schema,
final byte[] data)
{

}
}

private static SMFParserProviderType findParserProvider(
Expand Down
17 changes: 15 additions & 2 deletions io7m-smfj-core/src/main/java/com/io7m/smfj/core/SMFHeaderType.java
Expand Up @@ -92,6 +92,17 @@ default long vertexCount()
@Value.Parameter
Map<SMFAttributeName, SMFAttribute> attributesByName();

/**
* @return The number of metadata elements in the file
*/

@Value.Parameter
@Value.Default
default long metaCount()
{
return 0L;
}

/**
* Check preconditions for the type.
*/
Expand Down Expand Up @@ -120,7 +131,8 @@ default void checkPreconditions()
if (attribute_opt.isDefined()) {
if (!Objects.equals(attribute, attribute_opt.get())) {
final StringBuilder sb = new StringBuilder(128);
sb.append("An attribute that appears in the ordered list does not match that in the named map.");
sb.append(
"An attribute that appears in the ordered list does not match that in the named map.");
sb.append(System.lineSeparator());
sb.append(" Attribute: ");
sb.append(attribute.name());
Expand All @@ -129,7 +141,8 @@ default void checkPreconditions()
}
} else {
final StringBuilder sb = new StringBuilder(128);
sb.append("An attribute that appears in the ordered list does not exist in the named map.");
sb.append(
"An attribute that appears in the ordered list does not exist in the named map.");
sb.append(System.lineSeparator());
sb.append(" Attribute: ");
sb.append(attribute.name());
Expand Down
@@ -0,0 +1,76 @@
/*
* Copyright © 2016 <code@io7m.com> http://io7m.com
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
* IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/

package com.io7m.smfj.format.binary;

import com.io7m.junreachable.UnreachableCodeException;
import com.io7m.smfj.core.SMFAttribute;
import com.io7m.smfj.core.SMFAttributeName;
import com.io7m.smfj.core.SMFHeader;
import com.io7m.smfj.core.SMFSchemaIdentifier;
import com.io7m.smfj.format.binary.v1.SMFBV1HeaderReadableType;
import com.io7m.smfj.format.binary.v1.SMFBV1SchemaIDReadableType;
import javaslang.collection.List;
import javaslang.collection.Map;

/**
* Shared binary parser code.
*/

final class SMFBV1
{
private SMFBV1()
{
throw new UnreachableCodeException();
}

public static SMFHeader header(
final SMFBV1HeaderReadableType header_view,
final List<SMFAttribute> attributes,
final Map<SMFAttributeName, SMFAttribute> attributes_named)
{
final SMFBV1SchemaIDReadableType schema_id_view =
header_view.getSchemaReadable();

final SMFSchemaIdentifier.Builder schema_b =
SMFSchemaIdentifier.builder();
schema_b.setVendorID(schema_id_view.getVendorId());
schema_b.setSchemaID(schema_id_view.getSchemaId());
schema_b.setSchemaMajorVersion(schema_id_view.getSchemaVersionMajor());
schema_b.setSchemaMinorVersion(schema_id_view.getSchemaVersionMinor());

final SMFHeader.Builder header_b = SMFHeader.builder();
header_b.setVertexCount(
header_view.getVertexCount());
header_b.setTriangleCount(
header_view.getTriangleCount());
header_b.setTriangleIndexSizeBits(
(long) header_view.getTriangleIndexSizeBits());
header_b.setAttributesInOrder(
attributes);
header_b.setAttributesByName(
attributes_named);
header_b.setSchemaIdentifier(
schema_b.build());
header_b.setCoordinateSystem(
SMFBCoordinateSystems.unpack(
header_view.getCoordinateSystemReadable()));
header_b.setMetaCount(
(long) header_view.getMetaCount());

return header_b.build();
}
}
Expand Up @@ -17,6 +17,7 @@
package com.io7m.smfj.format.binary;

import com.io7m.jaffirm.core.Invariants;
import com.io7m.jaffirm.core.Postconditions;
import com.io7m.jnull.NullCheck;
import com.io7m.smfj.core.SMFAttribute;
import com.io7m.smfj.core.SMFAttributeName;
Expand Down Expand Up @@ -78,16 +79,20 @@ public final class SMFBV1Offsets
private final long vertices_data_offset;
private final long triangles_data_offset;
private final Map<SMFAttributeName, SMFBOctetRange> attributes_offsets;
private final long meta_data_offset;

private SMFBV1Offsets(
final long in_vertices_data_offset,
final long in_triangles_data_offset,
final long in_meta_data_offset,
final Map<SMFAttributeName, SMFBOctetRange> in_attributes_offsets)
{
this.vertices_data_offset =
in_vertices_data_offset;
this.triangles_data_offset =
in_triangles_data_offset;
this.meta_data_offset =
in_meta_data_offset;
this.attributes_offsets =
NullCheck.notNull(in_attributes_offsets, "Offsets");
}
Expand Down Expand Up @@ -164,7 +169,7 @@ public static SMFBV1Offsets fromHeader(
if (LOG.isDebugEnabled()) {
LOG.debug(
"vertex data offset: {}",
Long.valueOf(vertices_data_offset));
Long.toUnsignedString(vertices_data_offset));
}

long off = vertices_data_offset;
Expand All @@ -181,11 +186,8 @@ public static SMFBV1Offsets fromHeader(

final long data_size =
Math.multiplyExact(header.vertexCount(), data_element_size);

final long data_size_padded =
Math.multiplyExact(
Math.floorDiv(Math.addExact(data_size, 8L), 8L),
8L);
alignToNext8(data_size);

final SMFBOctetRange.Builder range_builder = SMFBOctetRange.builder();
range_builder.setOctetStart(off);
Expand Down Expand Up @@ -216,15 +218,69 @@ public static SMFBV1Offsets fromHeader(
if (LOG.isDebugEnabled()) {
LOG.debug(
"triangles offset: {}",
Long.valueOf(triangles_data_offset));
Long.toUnsignedString(triangles_data_offset));
}

final long triangle_size_one =
Math.multiplyExact(3L, header.triangleIndexSizeBits() / 8L);
final long triangle_size_all =
Math.multiplyExact(triangle_size_one, header.triangleCount());

final long meta_data_offset =
Math.addExact(triangles_data_offset, triangle_size_all);
final long meta_data_padded =
alignToNext8(meta_data_offset);

if (LOG.isDebugEnabled()) {
LOG.debug(
"meta data offset: {}",
Long.toUnsignedString(meta_data_padded));
}

Invariants.checkInvariantL(
meta_data_padded,
meta_data_padded % 8L == 0L,
meta_data_padded_now ->
"Offset " + meta_data_padded_now + " must be divisible by 8");

return new SMFBV1Offsets(
vertices_data_offset,
triangles_data_offset,
meta_data_padded,
attributes_offsets);
}

/**
* Align {@code offset} to the next 8-octet boundary. If {@code offset}
* is already divisible by 8, the function returns {@code offset}.
*
* @param offset The offset
*
* @return The aligned offset
*/

public static long alignToNext8(
final long offset)
{
final long result;
if (offset % 8L == 0L) {
result = offset;
} else {
result = Math.multiplyExact(Math.addExact(offset, 8L) / 8L, 8L);
}

LOG.trace(
"align {} -> {}",
Long.toUnsignedString(offset),
Long.toUnsignedString(result));

Postconditions.checkPostconditionL(
result,
Long.compareUnsigned(result, offset) >= 0,
x -> "Alignment must be correct");
return result;
}

/**
* @return The offset in octets of the start of the triangle data in the file
*/
Expand All @@ -243,6 +299,15 @@ public long verticesDataOffset()
return this.vertices_data_offset;
}

/**
* @return The offset in octets of the start of the meta data in the file
*/

public long metaDataOffset()
{
return this.meta_data_offset;
}

/**
* @return A map containing the offset in octets of the data in the file for
* each named attribute
Expand Down
Expand Up @@ -25,12 +25,10 @@
import com.io7m.smfj.core.SMFAttributeName;
import com.io7m.smfj.core.SMFComponentType;
import com.io7m.smfj.core.SMFHeader;
import com.io7m.smfj.core.SMFSchemaIdentifier;
import com.io7m.smfj.format.binary.v1.SMFBV1AttributeByteBuffered;
import com.io7m.smfj.format.binary.v1.SMFBV1AttributeType;
import com.io7m.smfj.format.binary.v1.SMFBV1HeaderByteBuffered;
import com.io7m.smfj.format.binary.v1.SMFBV1HeaderType;
import com.io7m.smfj.format.binary.v1.SMFBV1SchemaIDReadableType;
import com.io7m.smfj.parser.api.SMFParserEventsType;
import javaslang.collection.HashMap;
import javaslang.collection.List;
Expand Down Expand Up @@ -123,7 +121,10 @@ public void parseHeader()
Long.toUnsignedString((long) this.header_view.getTriangleIndexSizeBits()));
LOG.debug(
"expecting {} attributes",
Long.toUnsignedString((long) this.header_view.getAttributeCount()));
Long.toUnsignedString(this.header_view.getAttributeCount()));
LOG.debug(
"expecting {} metadata",
Integer.toUnsignedString(this.header_view.getMetaCount()));
}

this.parseHeaderAttributes();
Expand Down Expand Up @@ -205,8 +206,9 @@ public void parseTriangles()
this.offsets.trianglesDataOffset();

final long size =
Math.multiplyExact(3L,
(long) this.header_view.getTriangleIndexSizeBits() / 8L);
Math.multiplyExact(
3L,
(long) this.header_view.getTriangleIndexSizeBits() / 8L);
Invariants.checkInvariant(size != 0L, "Triangle size is nonzero");

for (long index = 0L;
Expand Down Expand Up @@ -886,28 +888,10 @@ private void checkHeaderAttributes()
});

if (!this.parserHasFailed()) {
final SMFBV1SchemaIDReadableType schema_id_view =
this.header_view.getSchemaReadable();

final SMFSchemaIdentifier.Builder vb =
SMFSchemaIdentifier.builder();
vb.setVendorID(schema_id_view.getVendorId());
vb.setSchemaID(schema_id_view.getSchemaId());
vb.setSchemaMajorVersion(schema_id_view.getSchemaVersionMajor());
vb.setSchemaMinorVersion(schema_id_view.getSchemaVersionMinor());

final SMFHeader.Builder hb = SMFHeader.builder();
hb.setVertexCount(this.header_view.getVertexCount());
hb.setTriangleCount(this.header_view.getTriangleCount());
hb.setTriangleIndexSizeBits((long) this.header_view.getTriangleIndexSizeBits());
hb.setAttributesInOrder(this.attributes);
hb.setAttributesByName(this.attributes_named);
hb.setSchemaIdentifier(vb.build());
hb.setCoordinateSystem(
SMFBCoordinateSystems.unpack(
this.header_view.getCoordinateSystemReadable()));

this.header = hb.build();
this.header = SMFBV1.header(
this.header_view,
this.attributes,
this.attributes_named);
this.offsets = SMFBV1Offsets.fromHeader(this.header);
}
}
Expand Down

0 comments on commit ca4826d

Please sign in to comment.