Skip to content

Commit

Permalink
Added crude support for KHR_texture_basisu
Browse files Browse the repository at this point in the history
  • Loading branch information
mrxz committed Nov 13, 2024
1 parent 24ebf49 commit 43a0c8d
Show file tree
Hide file tree
Showing 3 changed files with 143 additions and 0 deletions.
56 changes: 56 additions & 0 deletions lib/src/data_access/image_decoder.dart
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,9 @@ class ImageInfo {
case ImageCodec.WebP:
decoder = WebPInfoDecoder(subscription, completer);
break;
case ImageCodec.KTX2:
decoder = KTX2InfoDecoder(subscription, completer);
break;
default:
subscription.cancel();
completer.completeError(const UnsupportedImageFormatException());
Expand Down Expand Up @@ -743,6 +746,59 @@ class WebPInfoDecoder extends ImageInfoDecoder {
}
}

class KTX2InfoDecoder extends ImageInfoDecoder {
@override
String get mimeType => 'image/ktx2';

// Accumulate 48 bytes of KTX2 header
final Uint8List _buffer = Uint8List(48);
int _bufferIndex = 0;

KTX2InfoDecoder(StreamSubscription<List<int>> subscription,
Completer<ImageInfo> completer)
: super(subscription, completer);

@override
void add(List<int> bytes) {
final availableDataLength =
min(bytes.length, _buffer.length - _bufferIndex);
_buffer.setRange(_bufferIndex, _bufferIndex += availableDataLength, bytes);

if (_bufferIndex < 48) {
return;
}

subscription.cancel();

final byteData = _buffer.buffer.asByteData();

// Verify file identifier
if (byteData.getUint32(0, Endian.big) != 0xAB4B5458 ||
byteData.getUint32(4, Endian.big) != 0x203230BB ||
byteData.getUint32(8, Endian.big) != 0x0D0A1A0A) {
_abort(const InvalidDataFormatException('Invalid KTX2 file identifier.'));
return;
}

final vkFormat = byteData.getUint32(12, Endian.little);
final typeSize = byteData.getUint32(16, Endian.little);
final width = byteData.getUint32(20, Endian.little);
final height = byteData.getUint32(24, Endian.little);
final depth = byteData.getUint32(28, Endian.little);
final layer = byteData.getUint32(32, Endian.little);
final face = byteData.getUint32(36, Endian.little);
final level = byteData.getUint32(40, Endian.little);
final compression = byteData.getUint32(44, Endian.little);

// TODO: Proper conversion from vkFormat to format
var format = Format.Unknown;

completer.complete(ImageInfo._(mimeType, 8, format, width, height,
colorTransfer: _ColorTransfer.sRGB,
colorPrimaries: _ColorPrimaries.sRGB));
}
}

class UnsupportedImageFormatException implements Exception {
const UnsupportedImageFormatException();
}
Expand Down
85 changes: 85 additions & 0 deletions lib/src/ext/KHR_texture_basisu/khr_texture_basisu.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
/*
* # Copyright (c) 2016-2019 The Khronos Group Inc.
* #
* # Licensed under the Apache License, Version 2.0 (the "License");
* # you may not use this file except in compliance with the License.
* # You may obtain a copy of the License at
* #
* # http://www.apache.org/licenses/LICENSE-2.0
* #
* # Unless required by applicable law or agreed to in writing, software
* # distributed under the License is distributed on an "AS IS" BASIS,
* # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* # See the License for the specific language governing permissions and
* # limitations under the License.
*/

library gltf.extensions.khr_texture_basisu;

import 'package:gltf/src/base/gltf_property.dart';
import 'package:gltf/src/ext/extensions.dart';

const String IMAGE_KTX2 = 'image/ktx2';

const Extension khrTextureBasisUExtension = Extension(
'KHR_texture_basisu',
<Type, ExtensionDescriptor>{
Texture: ExtensionDescriptor(KhrTextureBasisUTexture.fromMap)
},
init: _init);

void _init(Context context) {
context.imageMimeTypes.add(IMAGE_KTX2);
}

const List<String> KHR_TEXTURE_BASISU_TEXTURE_MEMBERS = <String>[SOURCE];

class KhrTextureBasisUTexture extends GltfProperty
implements ResourceValidatable {
final int _sourceIndex;

Image _source;

Image get source => _source;

KhrTextureBasisUTexture._(
this._sourceIndex, Map<String, Object> extensions, Object extras)
: super(extensions, extras);

static KhrTextureBasisUTexture fromMap(
Map<String, Object> map, Context context) {
if (context.validate) {
checkMembers(map, KHR_TEXTURE_BASISU_TEXTURE_MEMBERS, context);
}

return KhrTextureBasisUTexture._(
getIndex(map, SOURCE, context, req: false),
getExtensions(map, KhrTextureBasisUTexture, context),
getExtras(map, context));
}

@override
void link(Gltf gltf, Context context) {
_source = gltf.images[_sourceIndex];
if (context.validate && _sourceIndex != -1) {
if (_source == null) {
context.addIssue(LinkError.unresolvedReference,
name: SOURCE, args: [_sourceIndex]);
} else {
_source.markAsUsed();
}
}
}

@override
void validateResources(Gltf gltf, Context context) {
final mimeType = _source?.mimeType ?? _source?.info?.mimeType;
if (mimeType != null && mimeType != IMAGE_KTX2) {
context
.addIssue(LinkError.textureInvalidImageMimeType, name: SOURCE, args: [
mimeType,
const [IMAGE_KTX2]
]);
}
}
}
2 changes: 2 additions & 0 deletions lib/src/ext/extensions.dart
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import 'package:gltf/src/ext/KHR_materials_unlit/khr_materials_unlit.dart';
import 'package:gltf/src/ext/KHR_materials_variants/KHR_materials_variants.dart';
import 'package:gltf/src/ext/KHR_materials_volume/khr_materials_volume.dart';
import 'package:gltf/src/ext/KHR_mesh_quantization/khr_mesh_quantization.dart';
import 'package:gltf/src/ext/KHR_texture_basisu/khr_texture_basisu.dart';
import 'package:gltf/src/ext/KHR_texture_transform/khr_texture_transform.dart';
import 'package:gltf/src/ext/VRMC_materials_mtoon/vrmc_materials_mtoon.dart';
import 'package:gltf/src/ext/VRMC_node_constraint/vrmc_node_constraint.dart';
Expand Down Expand Up @@ -129,6 +130,7 @@ const List<Extension> kDefaultExtensions = <Extension>[
khrMaterialsVariantsExtension,
khrMaterialsVolumeExtension,
khrMeshQuantizationExtension,
khrTextureBasisUExtension,
khrTextureTransformExtension,
vrmcMaterialMtoon,
vrmcNodeConstraint,
Expand Down

0 comments on commit 43a0c8d

Please sign in to comment.