fix: 安全审查 P3 问题修复(10项)
无障碍与用户体验: - 补全 OnboardingView/ProcessingView/ResultView/WallpaperGuideView 无障碍标注 - ContentView 添加后台切换截屏保护(模糊覆盖层) - EditorView iPad 右侧面板改为响应式宽度(minWidth:320, maxWidth:420) - ResultView CelebrationParticles 改用 Task 替代 DispatchQueue 延迟 - DesignSystem accessibility key 从中文改为英文 - EditorView/WallpaperGuideView 生成按钮 accentColor 统一为设计系统 - OnboardingView 第四页添加相册权限预告提示 核心库优化: - LivePhotoLogger 添加日志安全注释 - CacheManager.makeWorkPaths 添加磁盘空间预检查(<500MB 报错) - ImageFormatConverter BGRA/ARGB 转换改用 vImagePermuteChannels 加速 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -212,21 +212,25 @@ enum ImageFormatConverter {
|
||||
bytesPerRow: Int
|
||||
) -> [UInt8] {
|
||||
var result = [UInt8](repeating: 0, count: width * height * 4)
|
||||
let dstBytesPerRow = width * 4
|
||||
|
||||
for y in 0..<height {
|
||||
let srcRow = baseAddress.advanced(by: y * bytesPerRow).assumingMemoryBound(to: UInt8.self)
|
||||
let dstOffset = y * width * 4
|
||||
var srcBuffer = vImage_Buffer(
|
||||
data: baseAddress,
|
||||
height: vImagePixelCount(height),
|
||||
width: vImagePixelCount(width),
|
||||
rowBytes: bytesPerRow
|
||||
)
|
||||
|
||||
for x in 0..<width {
|
||||
let srcIdx = x * 4
|
||||
let dstIdx = dstOffset + x * 4
|
||||
|
||||
// BGRA -> RGBA swap
|
||||
result[dstIdx + 0] = srcRow[srcIdx + 2] // R
|
||||
result[dstIdx + 1] = srcRow[srcIdx + 1] // G
|
||||
result[dstIdx + 2] = srcRow[srcIdx + 0] // B
|
||||
result[dstIdx + 3] = srcRow[srcIdx + 3] // A
|
||||
}
|
||||
result.withUnsafeMutableBufferPointer { dstPtr in
|
||||
var dstBuffer = vImage_Buffer(
|
||||
data: dstPtr.baseAddress!,
|
||||
height: vImagePixelCount(height),
|
||||
width: vImagePixelCount(width),
|
||||
rowBytes: dstBytesPerRow
|
||||
)
|
||||
// BGRA → RGBA: 通道重排 [2,1,0,3]
|
||||
let permuteMap: [UInt8] = [2, 1, 0, 3]
|
||||
vImagePermuteChannels_ARGB8888(&srcBuffer, &dstBuffer, permuteMap, vImage_Flags(kvImageNoFlags))
|
||||
}
|
||||
|
||||
return result
|
||||
@@ -239,21 +243,25 @@ enum ImageFormatConverter {
|
||||
bytesPerRow: Int
|
||||
) -> [UInt8] {
|
||||
var result = [UInt8](repeating: 0, count: width * height * 4)
|
||||
let dstBytesPerRow = width * 4
|
||||
|
||||
for y in 0..<height {
|
||||
let srcRow = baseAddress.advanced(by: y * bytesPerRow).assumingMemoryBound(to: UInt8.self)
|
||||
let dstOffset = y * width * 4
|
||||
var srcBuffer = vImage_Buffer(
|
||||
data: baseAddress,
|
||||
height: vImagePixelCount(height),
|
||||
width: vImagePixelCount(width),
|
||||
rowBytes: bytesPerRow
|
||||
)
|
||||
|
||||
for x in 0..<width {
|
||||
let srcIdx = x * 4
|
||||
let dstIdx = dstOffset + x * 4
|
||||
|
||||
// ARGB -> RGBA swap
|
||||
result[dstIdx + 0] = srcRow[srcIdx + 1] // R
|
||||
result[dstIdx + 1] = srcRow[srcIdx + 2] // G
|
||||
result[dstIdx + 2] = srcRow[srcIdx + 3] // B
|
||||
result[dstIdx + 3] = srcRow[srcIdx + 0] // A
|
||||
}
|
||||
result.withUnsafeMutableBufferPointer { dstPtr in
|
||||
var dstBuffer = vImage_Buffer(
|
||||
data: dstPtr.baseAddress!,
|
||||
height: vImagePixelCount(height),
|
||||
width: vImagePixelCount(width),
|
||||
rowBytes: dstBytesPerRow
|
||||
)
|
||||
// ARGB → RGBA: 通道重排 [1,2,3,0]
|
||||
let permuteMap: [UInt8] = [1, 2, 3, 0]
|
||||
vImagePermuteChannels_ARGB8888(&srcBuffer, &dstBuffer, permuteMap, vImage_Flags(kvImageNoFlags))
|
||||
}
|
||||
|
||||
return result
|
||||
|
||||
Reference in New Issue
Block a user