Во всех нормальных форматах изображений и графических редакторах grayscale и indexed -- две разные сущности. К ним по-разному применяются фильтры, они по-разному интерполируются и т.д.
Сейчас при декодировании grayscale изображения подставляется костылик в виде искусственной палитры, которая заполняется оттенками серого. При этом тратится килобайт памяти на палитру и лишнее процессорное время на её заполнение программой/библиотекой и затем обращение к ней ядром при выводе изображения.
Ещё интереснее ситуация возникает при кодировании/сохранении изображений. Для того, чтобы определить тип картинки (grayscale/indexed), нужно пробежать всю палитру и проверить, а не совпадает ли она случайно с палитрой в оттенках серого? В этом месте можно подставить второй костыль в виде разделения типов grayscale/indexed на уровне приложения (каждого), но зачем?
Что предлагаю: добавить к списку допустимых значений esi (1,2,4,8,15,16,24 или 32 сейчас) ещё один -- 9. Он, конечно, не имеет "физического смысла" девяти битов на пиксель; это следует понимать как "почти восемь, только без палитры". При таком обозначении не нарушается логика функции: палитра присутствует у всех типов <= 8. Кроме того, 65-я функция поддерживает всякие экзотические 2, 15 и 16 бит на пиксель, почему там не должно найтись места для grayscale?
Естественно, я написал эти несколько строчек кода:
Spoiler:
Code: Select all
Index: kernel.asm
===================================================================
--- kernel.asm (revision 2725)
+++ kernel.asm (working copy)
@@ -4111,6 +4111,14 @@
;--------------------------------------
align 4
@@:
+ cmp esi, 9
+ jnz @f
+ mov ebp, putimage_get9bpp
+ mov esi, putimage_init9bpp
+ jmp sys_putimage_bpp
+;--------------------------------------
+align 4
+@@:
cmp esi, 15
jnz @f
mov ebp, putimage_get15bpp
@@ -4171,6 +4179,7 @@
putimage_init24bpp:
lea eax, [eax*3]
putimage_init8bpp:
+putimage_init9bpp:
ret
;-----------------------------------------------------------------------------
align 16
@@ -4191,6 +4200,14 @@
inc esi
ret 4
;-----------------------------------------------------------------------------
+align 16
+putimage_get9bpp:
+ lodsb
+ mov ah, al
+ shl eax, 8
+ mov al, ah
+ ret 4
+;-----------------------------------------------------------------------------
align 4
putimage_init1bpp:
add eax, ecx
Если будут возражения или я вдруг что-то упустил, обсудим.
Ах, да. Может, кто-то знает, как в функции putimage_get9bpp под спойлером можно лучше сделать броадкаст byte[esi] в байты eax? Можно только в три младших.