|
@@ -190,6 +190,10 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a
|
|
|
options -= {.return_header}
|
|
|
}
|
|
|
|
|
|
+ if .do_not_expand_channels in options || .do_not_expand_grayscale in options {
|
|
|
+ return img, .Unsupported_Option
|
|
|
+ }
|
|
|
+
|
|
|
first := compress.read_u8(ctx) or_return
|
|
|
soi := cast(image.JPEG_Marker)compress.read_u8(ctx) or_return
|
|
|
if first != 0xFF && soi != .SOI {
|
|
@@ -941,16 +945,25 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ orig_channels := img.channels
|
|
|
+
|
|
|
+ // We automatically expand grayscale images to RGB
|
|
|
+ if img.channels == 1 {
|
|
|
+ img.channels += 2
|
|
|
+ }
|
|
|
+
|
|
|
if .alpha_add_if_missing in options {
|
|
|
- img.channels += 1
|
|
|
+ img.channels += 1
|
|
|
+ orig_channels += 1
|
|
|
}
|
|
|
|
|
|
if resize(&img.pixels.buf, img.width * img.height * img.channels) != nil {
|
|
|
return img, .Unable_To_Allocate_Or_Resize
|
|
|
}
|
|
|
|
|
|
- switch img.channels {
|
|
|
- case 1:
|
|
|
+ switch orig_channels {
|
|
|
+ case 1: // Grayscale JPEG expanded to RGB
|
|
|
+ out := mem.slice_data_cast([]image.RGB_Pixel, img.pixels.buf[:])
|
|
|
out_idx := 0
|
|
|
for y in 0..<img.height {
|
|
|
mcu_row := y / BLOCK_SIZE
|
|
@@ -961,13 +974,15 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a
|
|
|
mcu_idx := mcu_row * block_width + mcu_col
|
|
|
pixel_idx := pixel_row * BLOCK_SIZE + pixel_col
|
|
|
|
|
|
- img.pixels.buf[out_idx] = cast(byte)blocks[mcu_idx][.Y][pixel_idx]
|
|
|
+ luma := cast(byte)blocks[mcu_idx][.Y][pixel_idx]
|
|
|
+ out[out_idx] = {luma, luma, luma}
|
|
|
+
|
|
|
out_idx += 1
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- case 2:
|
|
|
- out := mem.slice_data_cast([]image.GA_Pixel, img.pixels.buf[:])
|
|
|
+ case 2: // Grayscale JPEG expanded to RGBA
|
|
|
+ out := mem.slice_data_cast([]image.RGBA_Pixel, img.pixels.buf[:])
|
|
|
out_idx := 0
|
|
|
for y in 0..<img.height {
|
|
|
mcu_row := y / BLOCK_SIZE
|
|
@@ -979,10 +994,8 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a
|
|
|
mcu_idx := mcu_row * block_width + mcu_col
|
|
|
pixel_idx := pixel_row * BLOCK_SIZE + pixel_col
|
|
|
|
|
|
- out[out_idx] = {
|
|
|
- cast(byte)blocks[mcu_idx][.Y][pixel_idx],
|
|
|
- 255, // Alpha
|
|
|
- }
|
|
|
+ luma := cast(byte)blocks[mcu_idx][.Y][pixel_idx]
|
|
|
+ out[out_idx] = {luma, luma, luma, 255}
|
|
|
out_idx += 1
|
|
|
}
|
|
|
}
|
|
@@ -1034,6 +1047,7 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a
|
|
|
}
|
|
|
|
|
|
expect_EOI = true
|
|
|
+
|
|
|
case .TEM:
|
|
|
// TEM doesn't have a length, continue to next marker
|
|
|
case:
|