فهرست منبع

Expand grayscale JPEGs to RGB(A)

And handle grayscale jpeg example file in test suite.
Jeroen van Rijn 1 روز پیش
والد
کامیت
572b26a846
4فایلهای تغییر یافته به همراه35 افزوده شده و 10 حذف شده
  1. 24 10
      core/image/jpeg/jpeg.odin
  2. 2 0
      tests/core/.gitignore
  3. 1 0
      tests/core/download_assets.py
  4. 8 0
      tests/core/image/test_core_image.odin

+ 24 - 10
core/image/jpeg/jpeg.odin

@@ -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:

+ 2 - 0
tests/core/.gitignore

@@ -2,4 +2,6 @@
 *.zip
 *.png
 *.jpg
+*.qoi
+*.pbm
 math_big_test_library.*

+ 1 - 0
tests/core/download_assets.py

@@ -282,6 +282,7 @@ HMAC_DIGESTS = {
 
 	'emblem-1024.jpg':             "d7b7e3ffaa5cda04c667e3742752091d78e02aa2d3c7a63406af679ce810a0a86666b10fcab12cc7ead2fadf2f6c2e1237bc94f892a62a4c218e18a20f96dbe4",
 	'emblem-1024-progressive.jpg': "7a6f4b112bd7189320c58dcddb9129968bcf268798c1e0c4f2243c10b3e3d9a6962c9f142d9fd65f8fb31e9a1e899008cae22b3ffde713250d315499b412e160",
+	'emblem-1024-gray.jpg':        "4c25aaab92451e0452cdb165833b2b5a51978c2571de9d053950944667847666ba198d3001291615acda098ebe45b7d2d53c210c492f077b04a6bfe386f8a5fd",
 
 	'unicode.xml':                 "e0cdc94f07fdbb15eea811ed2ae6dcf494a83d197dafe6580c740270feb0d8f5f7146d4a7d4c2d2ea25f8bd9678bc986123484b39399819a6b7262687959d1ae",
 }

+ 8 - 0
tests/core/image/test_core_image.odin

@@ -51,6 +51,7 @@ Blend_BG_Keep        :: image.Options{.blend_background, .alpha_add_if_missing}
 Return_Metadata      :: image.Options{.return_metadata}
 No_Channel_Expansion :: image.Options{.do_not_expand_channels, .return_metadata}
 
+
 Dims :: struct {
 	width:     int,
 	height:    int,
@@ -2375,6 +2376,13 @@ Basic_JPG_Tests := []Test{
 			{Default,   .Unsupported_Frame_Type, {1024, 1024, 3, 8}, 0x_46a29e0f},
 		},
 	},
+	{
+		"emblem-1024-gray", {
+			{Default,              nil,                 {1024, 1024, 3, 8}, 0x_4115d669},
+			{Alpha_Add,            nil,                 {1024, 1024, 4, 8}, 0x_db496297},
+			{No_Channel_Expansion, .Unsupported_Option, {1024, 1024, 1, 8}, 0},
+		},
+	},
 }
 
 @test