-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathdecode.go
More file actions
71 lines (65 loc) · 2.63 KB
/
Copy pathdecode.go
File metadata and controls
71 lines (65 loc) · 2.63 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
package godicom
import (
"context"
"fmt"
"github.com/godicom-dev/godicom/uid"
)
// DecodeDataset decodes a DICOM dataset (no preamble / File Meta) using
// transfer syntax ts. Suitable for DIMSE Identifiers and C-STORE datasets.
func DecodeDataset(data []byte, ts UID) (*Dataset, error) {
return DecodeDatasetContext(context.Background(), data, ts)
}
// DecodeDatasetContext is like DecodeDataset but uses ctx for logging.
func DecodeDatasetContext(ctx context.Context, data []byte, ts UID) (*Dataset, error) {
info, known := uid.Lookup(ts)
if !known || !info.IsTransferSyntax {
return nil, fmt.Errorf(
"godicom: Transfer Syntax UID %q is not a known transfer syntax; use DecodeDatasetEncoding",
ts,
)
}
logDebug(loggerContext(ctx, nil, ComponentReader), "decode dataset",
AttrTransferSyntax, string(ts),
AttrLen, len(data),
)
payload := data
if ts.IsDeflated() {
inflated, err := inflateRaw(data)
if err != nil {
return nil, fmt.Errorf("godicom: error inflating dataset: %w", err)
}
payload = inflated
}
return DecodeDatasetEncodingContext(ctx, payload, info.IsImplicitVR, info.IsLittleEndian)
}
// DecodeDatasetEncoding decodes a DICOM dataset with explicit VR/endian flags.
func DecodeDatasetEncoding(data []byte, isImplicitVR, isLittleEndian bool) (*Dataset, error) {
return DecodeDatasetEncodingContext(context.Background(), data, isImplicitVR, isLittleEndian)
}
// DecodeDatasetEncodingContext is like DecodeDatasetEncoding but uses ctx for logging.
func DecodeDatasetEncodingContext(ctx context.Context, data []byte, isImplicitVR, isLittleEndian bool) (*Dataset, error) {
if isImplicitVR && !isLittleEndian {
return nil, fmt.Errorf("godicom: implicit VR and big endian is not a valid encoding combination")
}
ctx = loggerContext(ctx, nil, ComponentReader)
if len(data) == 0 {
ds := NewDataset()
ds.SetOriginalEncoding(isImplicitVR, isLittleEndian, nil)
return ds, nil
}
ds := NewDataset()
// No dict: these entry points take no ReadOptions, so they resolve against
// PS3.6. A caller with a vendor's private dictionary to apply reads through
// ReadBytes with Force set, which takes one; giving these four functions an
// options parameter is a wider change than the dictionary alone justifies.
rc := &readContext{data: data, ctx: ctx}
enc := EncodingInfo{IsImplicitVR: isImplicitVR, IsLittleEndian: isLittleEndian}
_, err := readDatasetElements(data, 0, int64(len(data)), ds, codecContext{EncodingInfo: enc}, nil, rc)
if err != nil {
return nil, fmt.Errorf("godicom: error decoding dataset: %w", err)
}
ds.originalEnc = enc
propagateEncoding(ds, ds.originalEnc)
captureOriginalCharsets(ds)
return ds, nil
}