Skip to content

Commit 45e8d69

Browse files
authored
Rename clsid to encoderCLSID and add label to corresponding init(). (#1295)
This PR adjusts the (experimental) extensions to `AttachableImageFormat` used for Windows support so that the `CLSID` value we use is explicitly defined in the API (not just documentation) as the _encoder_ CLSID. The Windows SDK also specifies _decoder_ CLSIDs and _container GUIDs_ which could be mistakenly passed here but which won't work correctly. Also some tweaks to documentation on the Apple side to match changes on the Windows side. ### Checklist: - [x] Code and documentation should follow the style of the [Style Guide](https://github.com/apple/swift-testing/blob/main/Documentation/StyleGuide.md). - [x] If public symbols are renamed or modified, DocC references should be updated.
1 parent d0917ae commit 45e8d69

File tree

4 files changed

+42
-28
lines changed

4 files changed

+42
-28
lines changed

Sources/Overlays/_Testing_CoreGraphics/Attachments/AttachableImageFormat+UTType.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,9 @@ extension AttachableImageFormat {
6363

6464
/// The content type corresponding to this image format.
6565
///
66+
/// For example, if this image format equals ``png``, the value of this
67+
/// property equals [`UTType.png`](https://developer.apple.com/documentation/uniformtypeidentifiers/uttype-swift.struct/png).
68+
///
6669
/// The value of this property always conforms to [`UTType.image`](https://developer.apple.com/documentation/uniformtypeidentifiers/uttype-swift.struct/image).
6770
///
6871
/// @Metadata {

Sources/Overlays/_Testing_WinSDK/Attachments/AttachableImageFormat+CLSID.swift

Lines changed: 35 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ extension AttachableImageFormat {
125125
///
126126
/// - Returns: An instance of `CLSID` referring to a a WIC image encoder, or
127127
/// `nil` if one could not be determined.
128-
private static func _computeCLSID(forPathExtension pathExtension: UnsafePointer<CWideChar>) -> CLSID? {
128+
private static func _computeEncoderCLSID(forPathExtension pathExtension: UnsafePointer<CWideChar>) -> CLSID? {
129129
let encoderPathExtensionsByCLSID = (try? _encoderPathExtensionsByCLSID.get()) ?? [:]
130130
return encoderPathExtensionsByCLSID
131131
.first { _, extensions in
@@ -145,9 +145,9 @@ extension AttachableImageFormat {
145145
///
146146
/// - Returns: An instance of `CLSID` referring to a a WIC image encoder, or
147147
/// `nil` if one could not be determined.
148-
private static func _computeCLSID(forPathExtension pathExtension: String) -> CLSID? {
148+
private static func _computeEncoderCLSID(forPathExtension pathExtension: String) -> CLSID? {
149149
pathExtension.withCString(encodedAs: UTF16.self) { pathExtension in
150-
_computeCLSID(forPathExtension: pathExtension)
150+
_computeEncoderCLSID(forPathExtension: pathExtension)
151151
}
152152
}
153153

@@ -160,14 +160,14 @@ extension AttachableImageFormat {
160160
///
161161
/// - Returns: An instance of `CLSID` referring to a a WIC image encoder, or
162162
/// `nil` if one could not be determined.
163-
private static func _computeCLSID(forPreferredName preferredName: String) -> CLSID? {
163+
private static func _computeEncoderCLSID(forPreferredName preferredName: String) -> CLSID? {
164164
preferredName.withCString(encodedAs: UTF16.self) { (preferredName) -> CLSID? in
165165
// Get the path extension on the preferred name, if any.
166166
var dot: PCWSTR?
167167
guard S_OK == PathCchFindExtension(preferredName, wcslen(preferredName) + 1, &dot), let dot, dot[0] != 0 else {
168168
return nil
169169
}
170-
return _computeCLSID(forPathExtension: dot + 1)
170+
return _computeEncoderCLSID(forPathExtension: dot + 1)
171171
}
172172
}
173173

@@ -185,14 +185,14 @@ extension AttachableImageFormat {
185185
/// encoder is used.
186186
///
187187
/// This function is not part of the public interface of the testing library.
188-
static func computeCLSID(for imageFormat: Self?, withPreferredName preferredName: String) -> CLSID {
189-
if let clsid = imageFormat?.clsid {
188+
static func computeEncoderCLSID(for imageFormat: Self?, withPreferredName preferredName: String) -> CLSID {
189+
if let clsid = imageFormat?.encoderCLSID {
190190
return clsid
191191
}
192192

193193
// The developer didn't specify a CLSID, or we couldn't figure one out from
194194
// context, so try to derive one from the preferred name's path extension.
195-
if let inferredCLSID = _computeCLSID(forPreferredName: preferredName) {
195+
if let inferredCLSID = _computeEncoderCLSID(forPreferredName: preferredName) {
196196
return inferredCLSID
197197
}
198198

@@ -215,7 +215,7 @@ extension AttachableImageFormat {
215215
static func appendPathExtension(for clsid: CLSID, to preferredName: String) -> String {
216216
// If there's already a CLSID associated with the filename, and it matches
217217
// the one passed to us, no changes are needed.
218-
if let existingCLSID = _computeCLSID(forPreferredName: preferredName), clsid == existingCLSID {
218+
if let existingCLSID = _computeEncoderCLSID(forPreferredName: preferredName), clsid == existingCLSID {
219219
return preferredName
220220
}
221221

@@ -229,9 +229,12 @@ extension AttachableImageFormat {
229229
return preferredName
230230
}
231231

232-
/// The `CLSID` value corresponding to the WIC image encoder for this image
233-
/// format.
234-
public var clsid: CLSID {
232+
/// The `CLSID` value of the Windows Imaging Component (WIC) encoder class
233+
/// that corresponds to this image format.
234+
///
235+
/// For example, if this image format equals ``png``, the value of this
236+
/// property equals [`CLSID_WICPngEncoder`](https://learn.microsoft.com/en-us/windows/win32/wic/-wic-guids-clsids#wic-guids-and-clsids).
237+
public var encoderCLSID: CLSID {
235238
switch kind {
236239
case .png:
237240
CLSID_WICPngEncoder
@@ -242,25 +245,31 @@ extension AttachableImageFormat {
242245
}
243246
}
244247

245-
/// Construct an instance of this type with the given `CLSID` value and
246-
/// encoding quality.
248+
/// Construct an instance of this type with the `CLSID` value of a Windows
249+
/// Imaging Component (WIC) encoder class and the desired encoding quality.
247250
///
248251
/// - Parameters:
249-
/// - clsid: The `CLSID` value corresponding to a WIC image encoder to use
250-
/// when encoding images.
252+
/// - encoderCLSID: The `CLSID` value of the Windows Imaging Component
253+
/// encoder class to use when encoding images.
251254
/// - encodingQuality: The encoding quality to use when encoding images. For
252255
/// the lowest supported quality, pass `0.0`. For the highest supported
253256
/// quality, pass `1.0`.
254257
///
255258
/// If the target image encoder does not support variable-quality encoding,
256259
/// the value of the `encodingQuality` argument is ignored.
257260
///
258-
/// If `clsid` does not represent an image encoder type supported by WIC, the
259-
/// result is undefined. For a list of image encoders supported by WIC, see
260-
/// the documentation for the [`IWICBitmapEncoder`](https://learn.microsoft.com/en-us/windows/win32/api/wincodec/nn-wincodec-iwicbitmapencoder)
261+
/// If `clsid` does not represent an image encoder class supported by WIC, the
262+
/// result is undefined. For a list of image encoder classes supported by WIC,
263+
/// see the documentation for the [`IWICBitmapEncoder`](https://learn.microsoft.com/en-us/windows/win32/api/wincodec/nn-wincodec-iwicbitmapencoder)
261264
/// class.
262-
public init(_ clsid: CLSID, encodingQuality: Float = 1.0) {
263-
self.init(kind: .systemValue(clsid), encodingQuality: encodingQuality)
265+
public init(encoderCLSID: CLSID, encodingQuality: Float = 1.0) {
266+
if encoderCLSID == CLSID_WICPngEncoder {
267+
self = .png
268+
} else if encoderCLSID == CLSID_WICJpegEncoder {
269+
self = .jpeg
270+
} else {
271+
self.init(kind: .systemValue(encoderCLSID), encodingQuality: encodingQuality)
272+
}
264273
}
265274

266275
/// Construct an instance of this type with the given path extension and
@@ -286,11 +295,13 @@ extension AttachableImageFormat {
286295
public init?(pathExtension: String, encodingQuality: Float = 1.0) {
287296
let pathExtension = pathExtension.drop { $0 == "." }
288297

289-
guard let clsid = Self._computeCLSID(forPathExtension: String(pathExtension)) else {
298+
let encoderCLSID = pathExtension.withCString(encodedAs: UTF16.self) { pathExtension in
299+
Self._computeEncoderCLSID(forPathExtension: pathExtension)
300+
}
301+
guard let encoderCLSID else {
290302
return nil
291303
}
292-
293-
self.init(clsid, encodingQuality: encodingQuality)
304+
self.init(encoderCLSID: encoderCLSID, encodingQuality: encodingQuality)
294305
}
295306
}
296307
#endif

Sources/Overlays/_Testing_WinSDK/Attachments/_AttachableImageWrapper+AttachableWrapper.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ extension _AttachableImageWrapper: Attachable, AttachableWrapper where Image: At
4141

4242
// Create the encoder.
4343
let encoder = try withUnsafePointer(to: IID_IWICBitmapEncoder) { [preferredName = attachment.preferredName] IID_IWICBitmapEncoder in
44-
var encoderCLSID = AttachableImageFormat.computeCLSID(for: imageFormat, withPreferredName: preferredName)
44+
var encoderCLSID = AttachableImageFormat.computeEncoderCLSID(for: imageFormat, withPreferredName: preferredName)
4545
var encoder: UnsafeMutableRawPointer?
4646
let rCreate = CoCreateInstance(
4747
&encoderCLSID,
@@ -117,7 +117,7 @@ extension _AttachableImageWrapper: Attachable, AttachableWrapper where Image: At
117117
}
118118

119119
public borrowing func preferredName(for attachment: borrowing Attachment<_AttachableImageWrapper>, basedOn suggestedName: String) -> String {
120-
let clsid = AttachableImageFormat.computeCLSID(for: imageFormat, withPreferredName: suggestedName)
120+
let clsid = AttachableImageFormat.computeEncoderCLSID(for: imageFormat, withPreferredName: suggestedName)
121121
return AttachableImageFormat.appendPathExtension(for: clsid, to: suggestedName)
122122
}
123123
}

Tests/TestingTests/AttachmentTests.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -821,11 +821,11 @@ extension AttachmentTests {
821821
}
822822

823823
@MainActor @Test func pathExtensionAndCLSID() {
824-
let pngCLSID = AttachableImageFormat.png.clsid
824+
let pngCLSID = AttachableImageFormat.png.encoderCLSID
825825
let pngFilename = AttachableImageFormat.appendPathExtension(for: pngCLSID, to: "example")
826826
#expect(pngFilename == "example.png")
827827

828-
let jpegCLSID = AttachableImageFormat.jpeg.clsid
828+
let jpegCLSID = AttachableImageFormat.jpeg.encoderCLSID
829829
let jpegFilename = AttachableImageFormat.appendPathExtension(for: jpegCLSID, to: "example")
830830
#expect(jpegFilename == "example.jpeg")
831831

0 commit comments

Comments
 (0)