МУЛТИМЕДИЙНО  
ОБУЧЕНИЕ   Основи на цвета Аудио формати Видео формати Изпитен тест Полезни връзки
Формати за неподвижни изображения

І Въведение І
І Компресия на данните І Пакетиране на пикселите І
І "RLE" - кодиране с променлива дължина на думата І
І Видове І Ниво бит, байт и пиксел І Вертикално дублиращи пакети І
І "LZW" - Лемпел-Зив-Уелш беззагубна компресия І
І Разликово кодиране І Вариации на "LZW" алгоритъма І
І "CCITT" - Хъфман кодиране І
І Едномерно кодиране "Group 3" І "TIFF" компресия - тип 2 І Двумерно кодиране "Group 3" І Двумерно кодиране "Group 4" І
І "JPEG" компресия І
І Основи на "JPEG" І
І Трансформация І Децимация І Дискретно косинус преобразуване І Квантуване І Кодиране І
І Разширение на "JPEG" - част I І
І Прогресивно предаване на изображението І Аритметично кодиране І Беззагубна "JPEG" компресия І
І Разширение на "JPEG" - част II І
І Променливи коефициенти на квантуване І Избор на регион І Разделяне на подизображения І
І "BMP" І
І Файлова структура І
І Версия 1.0 І Версия 2.0 І Версия 3.0 І Версия 3.0 за "Windows NT" І Версия 4.0 І
І Цветова палитра І Видове "BMP" файлове І Полезни данни и компресия І
І "GIF" І

І Файлова структура І
І "GIF87a" І
І Заглавна част І "Logical Screen Descriptor" І Глобална цветова таблица І "Local Image Descriptor" І Локална цветова таблица І Полезни данни І
"Trailer" І
І "GIF89a" І
І "Graphics Control Extension" І "Plain Text Extension" І "Application Extension" І "Comment Extension" І
І "JPEG" І
І Файлова структура І
І "PNG" І
І Файлова структура І
І Задължителни парчета І
І "IHDR" І "PLTE" І "IDAT" І "IEND" І
І Допълнителни парчета І
І "bKGD" І "cHRM" І "gAMA" І "hIST" І "pHYs" І "sBIT" І "tEXt" І "tIME" І "tRNS" І Парче за компресираната текстова информация І
І Полезни данни І Канал за прозрачност І "Interlacing" І Компресия І
І "TIFF" І
І Файлова структура І
І "IFH" І "IFD" І "Tags" І
І Организация на данните в етикетите І Полезни данни І Компресия І
І "PCX" І
І Файлова структура І
І Заглавна част І Цветова палитра І

І Компресия І Декодиране І Кодиране І Полезни данни І
І "WMF" І
І Файлова структура І Съвместимост І Съхранение І

       
 


Като цяло форматите за неподвижни изображения се делят на две големи групи – растерни и векторни. Растерните са изградени от матрица от пиксели, като всеки пиксел има собствен цвят, записан като бинарно число. Някои от най-популярните растерни формати са “BMP (Bitmap)”, “DIB (Device Independent Bitmap)”, “GIF (Graphic Interchange Format)”, “JPEG (Joint Photograph Experts Group)”, “TIFF (Tag Image File Format)”, “PNG (Portable Network Graphics)” и “PCX (Paintbrush file format)”.

“BMP” файловете са всъщност стандартизиран формат за неподвижни изображения, въведен от Майкрософт и внедрен в техните операционни системи (“Windows”, ”DOS”). Поддържа само "RGB” цветовото пространство и от 1 до 32 бита на пиксел. Поради липсата на компресия този формат не се налага като стандарт за Интернет изображения. “DIB” форматът e наследника на “BMP”, има същото разширение, но е независим спрямо системата, на която се изобразява, защото цветовото му пространство е адаптивно към крайното устройство. Ако става въпрос за принтер примерно, цветовият модел се преобразува в “CMY(K)” и тогава се праща за отпечатване.

“GIF” форматът използва беззагубна компресия “LZW”, и заедно с другите си предимства като прозрачност и възможност за анимиране е един от най-разпространените формати в Интернет. Неговият недостатък е, че палитрата му позволява само 256 цвята, но пък така се постига висок коефициент на компресия.

“JPEG” е другият файлов формат, широко разпространен в Интернет. Неговата компресия е със загуби, тоест намаляването на големината на файла става за сметка на неговото качество. Може да се постигне такава компресия, че файлът да стане на половината от големината на същото изображение, но в “BMP” формат, и пак да изглежда качествено. Принципно “JPEG” файловете стават по-големи от “GIF”, но това се дължи на факта, че тяхната палитра съдържа много повече от 256 цвята.

“TIFF” форматът е много широко използван и разпространен в предпечатната индустрия. Поддържа всички по-известни модели на цветовете – "RGB”, “Indexed”, “CMY(K)” и “Lab”. Форматът може да бъде компресиран, но са малко програмите, които могат да го прочетат в последствие, затова по-често се среща в некомпресиран вид.

“PNG” е един от най-новите формати за неподвижни изображения. Именно по тази причина доскоро няма поддръжка от уеб браузърите в Интернет. Многото му предимства над “GIF” обаче започват да го налагат като негов заместител. Освен възможността за прозрачност, форматът предлага и параметри за задаване на фон и гама корекция.

“PCX” форматът набира сила още от първите версии на програмата “Paintbrush” за “MS-DOS”. Тогава разбира се е имало въведени ограничения, свързани с технологиите за изобразяване – “EGA (Enhanced Graphic Adapter)”, като например не е имало възможност за палитра с повече от 16 цвята. При въвеждането на “VGA (Virtual Graphics Array)” формата цветовете се увеличават на 256. Сега форматът позволява 24-битови изображения, но е запазил възможността да преобразува палитрата си така, че изображението да става както за “EGA”, така и за “VGA” графични адаптери.

Векторните изображения се състоят от група инструкции за пресъздаване на картината. Вместо да съхранява цвета за всеки пиксел на изображението, форматът създава вектор, който съдържа всички инструкции, нужни за пресъздаването на формата, големината, позицията и цвета на всеки обект от изображението. Типичен представител на векторните файлови формати е “WMF (Windows Metafile Format)”. Разработен от Майкрософт, той предлага много по-качествени и изчистени изображения от всички растерни формати и най-важното – предоставя голям набор от възможности за обработка. Едно векторно изображение винаги може да се преобразува в растерно посредством процес, наречен растеризация. Той се състои в налагане на матрица върху векторното изображение и определяне на цвета за всеки пиксел от нея. Важно тук е да се зададе нужната големина на изходното растерно изображение, защото ако то е по-малко от необходимото и се наложи разтягане след растеризацията, качеството му ще се влоши рязко. Веднъж преобразувано в растерно, векторното изображение губи параметрите си на такова. Възможно е и обратно преобразуване – от растерно във векторно, но то е далеч по-сложно. При него се използва специален трасиращ софтуер, който открива ръбовете на обектите в изображението и превръща получената информация за формата във векторни графични обекти. Методът обаче може да се окаже несполучлив за фотографски снимки [4].

“ICO (Windows Icon Format)” – този формат за неподвижни изображения се различава от досегашните и затова се разглежда отделно. Той има възможност да съхранява няколко изображения в един файл и това му свойство го прави много полезен в някои случаи. Начинът на работа е изключително прост, но пък и много ефективен – когато “Windows” покаже лист с файлове, той проверява техните параметри, свързани с показването им на екрана, и тогава определя точно кое изображение да извлече от всички съхранени в ".ico” файла. Ако например е избран файлов лист с малки иконки, то от съответния ".ico” файл се извлича картинката с размери 16 x16 и например 256 цвята ( зависи от това в какъв режим на дисплей е мониторът ). Ако обаче такова изображение липсва във файла, “Windows” избира най-близкото до търсените параметри изображение. Например в ".ico” файла нека има съхранени 2 изображения със следните параметри:

изображение

размер ( битове )

цветност (битове на пиксел)

иконка №1

32х32

8 бита/пиксел

иконка №2

48х48

32 бита/пиксел

Ако “Windows” търси 16х16 иконка е явно, че няма да я намери. Тогава ще използва иконка №1, защото тя е най-близо до зададените търсещи параметри. Когато се създава ".ico” файл, трябва да се имат предвид няколко изображения, избрани по стандарт, с различна големина и цветност, за да се избегне по-горният проблем. Стандартните изображения са: 16x16, 32x 32, 48x48, като всяко от тях трябва да присъства в следните три разновидности: 4 бита / пиксел, 8 бита / пиксел и 32 бита / пиксел. Друг плюс на “ICO” формата е, че поддържа прозрачност, която обаче се реализира по различен начин за изображенията с цветност 32 бита / пиксел и тези с по-ниска. За последните просто имаме пиксели, които са прозрачни и не се изобразяват на екрана, докато при 32-битовите изображения имаме 8 бита за алфа канал ( от 0 до 255 ). Колкото по-ниска е стойността му, толкова по-прозрачен е даденият пиксел. При стойност нула той е изцяло прозрачен.

обратно към навигационното меню

Методи за компресия на неподвижни изображения

Компресия на данните

Компресията е процес, който редуцира големината на даден информационен блок. В компютърната графика това е много важно, тъй като се цели да се съберат колкото се може повече полезни данни на по-малко пространство. Също може да се приложи, когато става дума за дадена големина на блок памет, в който да се смести изображението. Разглеждайки различните файлови формати, ще направи впечатление, че терминът "кодиране на данни ” се използва вместо "алгоритми за компресия ”, но той означава много повече от компресия на данните, като включва алгоритми както за криптиране, така и за предаване на данните.

Компресорът има възможност да компресира и декомпресира данните, в зависимост от това какво му е зададено, докато декомпресорът може да изпълнява функциите си само ако има информация за алгоритъма, използван за компресия в компресора. Следователно ако се налага манипулация на графични файлове, се изисква не само добро познаване на файловите формати, но и на използвания алгоритъм за компресия. Най-често използваните са:

Компресията на данните става по различен начин за двата основни типа графични данни – растерните и векторните. При растерните обикновено се компресира само изображението, тоест заглавната част, палитрата и т.н. остават некомпресирани.

При векторните файлови формати не може да се говори за компресия както при растерните. Това се дължи на факта, че файловете всъщност се състоят от математически описания на изображението вместо от самото изображение и има няколко основни причини, поради които не се прилага компресия на такива файлове:

  • изображението вече е представено достатъчно компактно и последвало компресиране би имало или никакъв, или нищожно малък ефект върху големината на файла;
  • обикновено проблемът при векторните изображения е, че се четат бързо, но бавно се реконструира изображението от описанието. Ако сме приложили компресия, следва, че ще има нужда от декомпресия, което само допълнително ще забави процеса на реконструкция.

Ако все пак има компресиран векторен файл, то компресията при него обхваща както описанието на изображението, така и заглавната част. Важно е да се знае, че алгоритмите за компресия дефинират само как се кодират данните, а не как се съхраняват в паметта.

Термините "некодирани данни ” и "некомпресирани данни ” се отнасят до информацията, преди тя да бъде компресирана, а "кодирани данни ” и "компресирани данни ” до тази след компресия. Терминът "коефициент на компресия ” дава съотношението между едни и същи данни в некомпресиран и компресиран вид. Така например коефициент на компресия 10:1 се счита за 5 пъти по-ефективен от 2:1. Следва, че данните, компресирани с 10:1, са пет пъти по-малки от компресираните с 2:1. Понеже на практика се компресират само изображенията, при отчитане коефициента на компресия трябва да се вземат предвид размерите на крайните файлове.

Въпреки че главното предназначение на компресията е да компресира данните, така че те да заемат по-малко място, това не става, като физически се смачкват данните в по-малки пакети. Просто се използват ефективни алгоритми за кодиране, които представят данните по друг по-компактен начин. Иначе казано – по-малко думи се използват да се изрази едно и също мнение, без обаче да се казва едно и също нещо. Разликите между методите за физическа и логическа компресия са на базата на това как данните се пренареждат в по-компактна форма. Физическата компресия се извършва върху данни без значение каква информация носят те – състои се в пренареждане на серии от битове в по-компактен вид. Получава се компресирана информация, която е свързана с оригинала само по механичен път, тоест ако се погледне компресирания файл и некомпресирания, няма да се открие каквато и да е било визуална връзка между тях. Методът е широко използван при компресия на неподвижни изображения.

Логическата компресия се свързва с процеса логическа субституция, което всъщност представлява заменяне на една буква, цифра или бинарен символ с друг. Например "Народна Република България ” може успешно да се замени с "НРБ ”. Примерът е удачен, защото информацията за логическата субституция се извлича директно от оригиналния текст и полученият стринг запазва донякъде значението на оригинала. От примера се разбира, че логическата компресия е базирана на това, което се съдържа във файла. Тя не се използва при работа с неподвижни изображения.

Методите за компресия могат да се разделят на симетрични и асиметрични. Симетричните използват едни и същи алгоритми както за компресия, така и за декомпресия. Употребяват се, когато се изисква процесът да е в реално време. Асиметричните методи използват два различни алгоритъма за компресия и декомпресия, като обикновено компресията е процесът изискващ повече време и ресурси. В това има голяма доза логика, тъй като ако правим база данни от изображения, то те ще бъдат компресирани само веднъж при въвеждането им в базата, но ще бъдат декомпресирани много пъти от потребители, които искат да ги видят, затова процесът на декомпресия трябва да е по-непретенциозен откъм ресурси и по-бърз от компресията. Асиметрични алгоритми, при които приоритетите на двата процеса са обърнати, са рядкост, но съществуват – примерно при създаване на “backup”, тоест презастраховане на важна информация. Вероятността тези файлове да бъдат отворени някога е малка, затова се изисква бърз алгоритъм за компресия, а изискванията за скоростта на декомпресия са занижени.

Някои кодери, базирани на библиотеки, като например “CCITT”, са направени да компресират само определен тип данни. Наричат се неадаптивни кодери и съдържат статични библиотеки от предварително дефинирани стрингове, срещани най-често в информацията, която ще се кодира. От друга страна има адаптивни кодери, които не съдържат никаква предварителна информация за данните, които ще се компресират. Пример за такъв кодер е “LZW”, при който се създават библиотеки на базата на информацията, която се кодира, като се започва от най-простите символи и се стига до най-сложните стрингове. Адаптивната компресия има способността да се настройва към всякакъв тип входни данни. Поради това й свойство на изхода се получава най-добрия възможен коефициент на компресия. Това е в пълен контраст с неадаптивните модели за компресия, които изпълняват условието, но само за типа данни, за които са предназначени. Съществуват и кодери, които са смесица от двата. Наричат се полу-адаптивни методи за кодиране. При тях кодирането става на два етапа – първият съставя библиотеката от стрингове, а вторият самото кодиране. При този метод винаги се изготвя оптимална библиотека на символите, преди да се премине към кодирането, следователно е доста по-бавен, но и по-точен, от адаптивния и неадаптивния метод.

Методите на компресия се делят още на беззагубни и със загуби. Беззагубна компресия имаме, когато при компресия на парче информация и последвала декомпресия, оригиналната информация се запазва на 100%, тоест нищо не е загубено или променено. Методите за компресия със загуби жертват част от информацията за сметка на по-добри коефициенти на компресия в сравнение с беззагубните методи. Някои от тях използват алгоритми, които се настройват според данните, които ще кодират, и така осигуряват максимална компресия, като се променя съвсем малко във визуалната информация. Други пък просто премахват от всеки пиксел информация, която смятат за маловажна и се получава що-годе добър резултат откъм визуално качество. Понякога термините "беззагубно ” и "със загуби ” се използват за описание качеството на едно изображение, което е погрешно. Загубата на данни в дадено изображение не винаги води до визуалното му влошаване. Наистина по-добре би било ако нямаме никакви загуби, но това по-скоро важи за текстови или бинарни файлове. Що се отнася до неподвижните изображения, кодирането "със загуби ” е не само приемливо, но понякога и желателно. Практиката потвърждава това. Например малка промяна в стойността на пиксел от изображение с висока резолюция би останала напълно незабележима освен ако разбира се, изображението не е едноцветно или пък има големи зони, запълнени с един и същи цвят. При черно-белите изображения нещата стоят малко по различно. Пикселът е или бял или черен, но дори тук е допустима промяна. Ако новият пиксел просто премества границата между бялото и черното с един пиксел, той ще бъде много трудно различим и съответно допустим.

В последно време алгоритмите със загуби претърпяват голямо развитие и много от тях вече могат да постигнат завидни коефициенти на компресия, като се запазва добро качество на изображението. Учените продължават да изследват човешкото зрение и на базата на него да подобряват съществуващите или да създават нови, още по-добри алгоритми за компресия.

обратно към навигационното меню

Пакетиране на пиксели

Процесът на пакетиране на пиксели не е метод за компресия на данни, а по-скоро ефикасен начин за съхраняването им в дълги байтови поредици в паметта. Широко разпространен е при растерните неподвижни изображения, тъй като се спестява значително количество памет. Например ако се работи с изображение, което използва 4 бита на пиксел, би било удобно да се отдели за всеки един от пикселите по един байт от паметта, защото това е най-малката адресируема единица в повечето компютърни системи. Този метод обаче води до загуба на половината памет, тъй като един байт съдържа 8 бита, а пикселът, с който се запълва, – само 4. Удобно е да се приложи пакетиране на пикселите, което означава да се съхранява вместо по един пиксел на байт по два. Така за едно изображение с 4096 пиксела ще са нужни само 2048 байта, вместо 4096. Иначе казано, нещата изглеждат така:

Процесът на пакетиране на пиксели изглежда най-логичното решение, което може да се вземе, но той си има и недостатъци. Паметта на хардуера за визуализация е организирана от масиви от байтове, всеки от които съхранява един пиксел или дори по-малко. Ако това е в сила, в действителност ще се окаже много по-бързо да се сложи само по един пиксел във всеки байт, отколкото по два, защото тогава при визуализацията ще се наложи да се ползват преместващи регистри за прочитане и визуализиране на втория пиксел в байта. Тоест трябва да се прецени на коя страна да натежи везната, като от едната имаме по-бързи времена за четене и визуализация, а от другата – намален размер на файла.

Компресията винаги дава както положителни, така и негативни последици. В случая недостатъците са, че се увеличава времето за разпакетиране на пикселите при визуализация; усложнява се организацията на буферите за данни при декомпресия; получава се по-голямо натоварване на процесора и т.н. Така ако се наложи създаването на програма за четене на различни формати за неподвижни изображения, поддръжката на всички методи за компресия, дефинирани в спецификацията на съответния формат, е задължителна. Ако пък се наложи създаването на програма за компресия на изображения, винаги трябва да се дефинират плюсовете и минусите на всеки от методите за компресия и да се използва този, който най-много приляга на целите.

В миналото, когато дисковото пространство и паметта били ограничени, въпросът за компресията на изображенията изобщо не бил на дневен ред, тя просто била задължителна. Днес нещата стоят по коренно различен начин, но въпреки това компресията продължава да се прилага и ще продължава и в бъдеще, защото понякога плюсовете от нея са значителни и не могат да се пренебрегнат, дори на фона на минусите.

обратно към навигационното меню

"RLE" - кодиране с променлива дължина на думата

“RLE” е метод за компресия, който се поддържа от доста от по-известните формати за неподвижни изображения като “TIFF”, “BMP” и “PCX”. При него могат да се компресират всякакъв вид данни без значение от информационното им съдържание, но то се отразява върху получения коефициент на компресия. “RLE” обикновено не постига някакви завидни коефициенти, но за сметка на това е лесен за създаване и бърз за изпълнение, което го прави предпочитан измежду вариантите за компресия с по-сложни методи и този изобщо да не се прилага компресия.

Принципът на действие на метода се основава на намаляване размера на повтарящи се символи. Обикновено тази поредица се кодира в два байта, като първият показва броя еднакви символи – брояч, а вторият – самия символ – стойност, който се повтаря в стринга. Некомпресирана поредица от 15 букви "А ” би заела цели 15 байта, докато чрез “RLE” те се свеждат само до 2 чрез следния запис – “15 А ”. Това се нарича “RLE” пакет, съдържащ двата байта, първият – 15 и вторият – А. Нов пакет се генерира винаги когато се смени символът в поредицата, която кодираме, или когато поредицата от съответния символ превишава 256 ( максималното число, което може да се събере в 8 бита или 1 байт ). За примерен стринг от вида: “AAAAAAbbbXXXXXt” се получават 4 двубайтови пакета от вида: "6 A3b5X1t”. Така от 15 байта некомпресирана информация се получават 8 байта компресирана или коефициент на компресия 2:1. Всичко до тук изглежда много добре, но в някои типове данни като например в произволен “ASCII” текст не се срещат такива дълги поредици от еднакви символи. За тях методът “RLE” е неудачен, защото неговият пакет винаги се състои минимум от 2 байта и ако нямаме поредица от повтарящи се символи или в най-добрия случай най-много два, повтарящи се един след друг, вместо свиване на информацията се получава по-голям изходен файл от входния, а това категорично противоречи на основната идея на компресията да свива данните. Например стрингът: “Xtmprsqzntwlfbb” след “RLE” ще стане “1X1t1m1p1r1s1q1z1n1t1w1l1f2b”.

Като цяло “RLE” алгоритмите са прости и бързи, но ефективността на компресията им зависи от съдържанието на изображението, което ще се кодира. Черно-бяло изображение, при което преобладава белият цвят, както е при сканирана страница от книга, би се кодирало много добре за ради дългите поредици от един и същи цвят, но затова пък пълноцветно изображение не би могло да получи каквато и да било компресия чрез “RLE” поради големия набор от цветове и комплексността на изображението.

обратно към навигационното меню

Видове “RLE”

Съществуват няколко разновидности на метода за компресия “RLE”. Обикновено данните от изображението се представят като едномерен поток от символи вместо като двумерна матрица. Най-разпространеният метод е, като се започва от най-горния ляв ъгъл и се движим надясно и надолу (a), но съществуват и други – по колони (b), на блокчета (c) или дори диагонално по зиг-заг (d):

Принципно методът “RLE” е беззагубен, но макар и рядко се срещат негови разновидности, които използват кодиране със загуби. Това довежда до по-добър коефициент на компресия за сметка на нулирането на няколко маловажни бита в даден пиксел, като така изображението не се поврежда видимо. Този вариант се използва главно при работа с изображения от заобикалящия ни свят, съдържащи много невидими за окото вариации на цветовете в стойностите на пикселите.

Важно при “RLE” кодерите е да се спира на края на всеки сканиран ред от кодираното изображение, защото така се намалява размерът на нужния буфер и се отстранява проблемът наречен “cross-coding” ( смесващо кодиране ), който представлява сливане на сканирани редове от изображението. Ако се получи такова смесване, изчезват краят и началото на предишния ред и на текущия. Възстановяването им е почти невъзможно. Въпреки всичко има случаи, когато не само не се избягва този проблем, а дори се използва целенасочено. Това спестява няколко байта памет, но процесът на декодиране се усложнява и отнема повече време. Положителната страна е, че се елиминира нуждата от организиране на изображението в редове за сканиране, макар повечето файлови спецификации изрично да констатират, че не само трябва да има такива редове, а и те трябва да се кодират индивидуално. Изискването се пренебрегва от много от приложенията, занимаващи се с кодиране на неподвижни изображения, и те ги представят като поредица от символи игнорирайки редовете за сканиране. Това често е причина изображения, кодирани с “RLE” ползвайки “cross-coding”, да се визуализират без проблеми на едни приложения, но да не могат да се заредят на други. За да са правилни декодирането и визуализацията, приложенията трябва да отчетат, че може да е ползван “cross-coding”, а не да разчитат, че кодирането е спирало на всеки сканиран ред, както е по спецификация. Краят на ред за сканиране се означава с маркер, който представлява уникален пакет, дефиниран в “RLE” спецификацията, и не може да бъде сбъркан. Дължината на тези маркери обикновено е 1 байт, така че кодирането им с 2 байта не довежда до особени промени в коефициента на компресия, тъй като те са нищожна част от цялата кодирана информация. Кодирането на всеки ред за сканиране индивидуално има и своите предимства най-вече когато се налага да се ползва само част от изображението. Ако изображение съдържа примерно 512 реда за сканиране, а се визуализират само тези между 100 и 110 и не се зане къде започват и къде свършват съответните редове ще се наложи приложението да декодира всички от 1 до 100, за да види къде започва стотният и в последствие да декодира и следващите 10. Разбира се, при наличието на маркери, отчитащи края на всеки ред, би било много по-лесно да се открие стотния, но въпреки всичко това не е ефективен начин. Конструирането на таблица на редовете за сканиране опростява неимоверно търсенето на отделни редове. Тя съдържа по един елемент за всеки ред, който от своя страна съдържа отместването на съответния ред спрямо началото. Така за откриване на десетия ред просто трябва да се види отместването, записано в десетия елемент на таблицата. Вместо отместване таблицата може да съдържа броя байтове, нужен за кодиране на всеки ред, тогава за откриване на десетия ред просто се събират стойностите на първите 9 клетки от таблицата и се получава на колко байта отместване от началото започва първият “RLE” пакет от ред 10.

обратно към навигационното меню

Ниво бит, байт и пиксел в “RLE”

“RLE” алгоритъмът изглежда по следния начин:

“RLE” алгоритмите за растерни изображения обикновено се делят на класове в зависимост от елементите, които се кодират. Трите основни класа, използвани от повечето графични файлови формати, са ниво бит, байт и пиксел.

При нивото бит се кодират няколко бита в една линия за сканиране, като се игнорират границите за байт и дума. Само еднобитовите монохромни изображения имат достатъчен брой поредици от еднакви битове, за да е ефективно това ниво на “RLE” кодиране. Обикновено се ползват еднобайтови пакети, които могат да кодират до 128 последователни еднакви символи, като най-старшият бит показва символа – 0 или 1, а другите 7 – броя повторения минус едно.

При нивото байт се кодират идентични байтови стойности при игнориране границите на битовете и думите в един ред за сканиране. Най-често се кодират двубайтови “RLE” пакети, като първият байт съдържа броя повторения на стойността на повтарящия се байт, а вторият – самата стойност. Често срещано е и двубайтово кодиране с възможност за съхранение на некодирани поредици от байтове вътре в кодирания поток. При такава схема седемте най-младши разряда на първия байт съдържат броя повторения минус едно, а най-старшият – 1 или 0, като единицата значи, че следва кодирана поредица във втория байт, а нулата – некодирана поредица. В първия случай кодираните поредици се декодират, като се прочита стойността на байта и съответно се повтаря толкова пъти, колкото е указано в 7-те младши бита на първия байт минус едно. Във втория случай байтовете се четат и записват така, както са. Нивото байт в “RLE” е много удобно, когато имаме изображение с 8 бита на пиксел.

При нивото пиксел се използват два или повече последователни байта от данни в един пиксел. В това ниво битовете се игнорират, а байтовете се броят само за определяне стойността на всеки пиксел. Големината на кодирания “RLE” пакет варира в зависимост от стойността на пиксела, който се кодира. Броят битове или байтове на пиксел се съхранява в заглавната част на изображението. Така например една 3-байтова стойност на пиксел се кодира с 4-байтов “RLE” пакет, като първият байт указва броя повторения на останалите 3, т.е. на пиксела. Методът на кодиране е същия, както при ниво байт, и е възможно вмъкване на некодирани пиксели в кодирания поток. Това отново става, като се отделя най-старшият разряд на първия байт за определяне на типа на поредицата от пиксели.

Нагледно трите нива в “RLE” се виждат на следната картинка:

Обикновено “RLE” методът анализира некомпресираната информация, за да определи дали да използва некомпресирана поредица от пакети. Ефективното ползване на това кодиране зависи от това колко поредици от такива пакети има в потока от данни. Съществува обаче и друг метод, който позволява некомпресирани поредици от символи да се добавят към кодирания поток от данни, без да бъдат капсулирани в пакети. Разглежда се схема на “RLE” кодиране, която използва три байта за представяне на поредиците от символи. В първия байт се съдържа флаг, чиято стойност показва, че следващите два байта са част от кодиран пакет. Вторият съдържа броя повторения на символа от поредицата, а третият самия символ. Схемата има следния вид:

При кодиране на едно-, дву– или 3-байтова схема данните винаги се записват директно в компресирания поток, докато при декодиране нещата стоят малко по-различно. Чете се всеки байт и се проверява дали е флаг. Ако да, то следва декодиране на следващите два байта и записът им в некомпресирания поток, но ако не е флаг, следва директен запис на следващите два байта в потока. Това изглежда един доста добър метод, но и той има своите недостатъци:

  • увеличава се оптималната дължина на поредиците от символи, за да е ефикасно кодирането – от 3 символа на 4.
  • ако некодираната поредица от символи съдържа стойност идентична на флага, следва да бъде компресирана в трибайтов пакет и той да бъде четен като поредица от един символ. Така се предотвратява появата на фалшиви флагове, но при наличието на няколко такива стойности, би се получил много нисък коефициент на компресия. Тогава може да се прибегне до смяна на стойността на флага с такава, която се среща най-рядко в некомпресираната поредица.

обратно към навигационното меню

Вертикално дублиращи пакети

Съществуват “RLE” алгоритми, които ползват различни по структура пакети с цел подобряване на компресията. Един от най-ефикасните използвани пакети е повтарящият ред за сканиране, известен също като вертикално дублиращ пакет. Той не съдържа реално никаква информация за реда за сканиране, а просто указва, че текущият ред е всъщност повторение на предишния. Нека например имаме изображение с 640 байта на ред за сканиране и всички пиксели върху него са с един и същи цвят. При двубайтови пакети и максимум 128 байта на пакет това означава, че кодираният поток ще е 10 байта. Изображението е такова, че първите му 100 реда са с един и същи цвят, което при 10 байта на ред означава 1000 байта за стоте реда. Използвайки обаче вертикално дублиращи пакети, нещата придобиват съвсем друг вид. Този пакет е само 1 байт и след кодиране на първата линия с 10 байта, само се долепят 99 вертикално дублиращи пакети, които общо са 99 байта, и се получава 109 байта кодиран поток вместо 1000. Дори ако вертикално дублиращият пакет имаше още един байт за броя линии, които трябва да се повторят, то само един такъв пакет би свършил работа със стойност на повторение 99. Така крайният кодиран поток би имал размер 12 байта, което при 64 000 байта некомпресирани данни е завиден коефициент на компресия. Ето как изглежда схемата с еднобайтов и двубайтов вертикално дублиращ пакет:

За съжаление този много удобен метод за компресия е зависим от компютърното приложение и поради тази причина е намерил място при малко формати, като най-известните от тях са ”IMG ( GEM Raster)” и “WPG (WordPerfect Graphics Metafile)”.

обратно към навигационното меню

"LZW" - Лемпел-Зив-Уелш беззагубна компресия

Това е един от най-използваните методи за компресия при неподвижните изображения. Внедрен е във форматите “GIF”, “TIFF” и "PNG”, а също е част и от стандарта за компресия по модем – “V.42”. През 1977 г. се създава първата версия на алгоритъма – “LZ77”, която повече се е използвала за компресия на текст и архивиране на програми. “LZ78” е алгоритъмът, който намира широко приложение при компресия на неподвижни растерни изображения. През 1984 г. този алгоритъм претърпява сериозни подобрения, като му се добавя поддръжка за високоскоростни дискови контролери. “LZW” може да работи с всякакъв тип данни, като компресията и декомпресията са доста бързи и не използват операции с плаваща запетая. Компресираните данни се записват като байтове, а не като думи, което е плюс.

“LZW” е известен като метод използващ субституция или така наречения алгоритъм, базиран на библиотеки. Тези библиотеки се създават на базата на информацията в некомпресирания поток от данни. На всеки нов стринг се присвоява код от библиотеката, с който той се идентифицира по-нататък. Получава се компресия, тъй като стойността, записана в изходния поток, е по-малка от оригиналния стринг, който представя. При декодиране се чете кодът от кодирания поток и се добавя в библиотека, ако все още го няма там. Следва превод на кода към оригинал и записването му в изходен некодиран поток. “LZW” е много по-добър от много подобни комресори на базата на библиотеки, тъй като при него не е нужно да се съхранява библиотеката, с която се кодира, за да се извърши декодирането. Това спестява много място при съхранение на кодираната информация.

При компресия на текстови файлове се инициализират първите 256 постъпили символа в библиотека, представяйки ги като фрази. Те всъщност са всички възможни букви / символи – еднобайтови стойности, които могат да се появат някога, а всички останали думи са комбинации от тях. Поради факта, че при кодиране и декодиране винаги се започва с тази инициализация, декодерът не се нуждае от кодиращата библиотека, тъй като той сам си я изгражда в процеса на декодиране. Алгоритъмът на компресия е следният, като се има предвид, че “K” е текущ символ, а “w” е съществуващ стринг:

Задава се примерна стойност “w = NIL”
начало на цикъла
прочита се символът “K”
ако “wK” съществува в библиотеката, то
“w = wK”
в противен случай
извежда се кодът за “w”
добавя се “wK” към библиотеката
“w = K”
край на цикъла

Примерна поредица от символи би се кодирала така:

/WED/WE/WEE/ WEB

входни символи

изходен код

нова кодова стойност и съответният стринг към нея

/W

/

256 = /W

E

W

257 = WE

D

E

258 = ED

/

D

259 = D/

WE

256

260 = /WE

/

E

261 = E/

WEE

260

262 = /WEE

/W

261

263 = E/W

EB

257

264 = WEB

<край>

B

 

Декодирането на получената кодова поредица пък става по следния начин:

/WED<256>E<260><261><257>B

входящ код

изходен стринг

нова кодова стойност и съответният стринг към нея

/

/

256 = /W

W

W

257 = WE

E

E

258 = ED

D

D

259 = D/

256

/W

260 = /WE

E

E

261 = E/

260

/WE

262 = /WEE

261

E/

263 = E/W

257

WE

264 = WEB

B

B

 

При “TIFF” формата пикселите се пакетират в байтове, преди да бъдат кодирани с “LZW”. Така един байт от библиотеката може да е стойност на пиксел, част от стойността на пиксел или няколко стойности на пиксели в зависимост от битовете на отчет и броя цветови канали на изображението. Този метод не е много удачен, когато имаме нечетен брой битове на отчет, защото тогава пакетираните байтове не отговарят на оригиналните пиксели.

Форматът “GIF” изисква всеки входящ символ в библиотеката да бъде стойност на един пиксел и понеже форматът поддържа изображения с максимално 8 бита на отчет, то входните символи са максимум 256. Следва инициализация, подобна на тази при текстовите файлове. Тук проблемът с нечетния брой битове на отчет не седи на дневен ред, но пък е недостатък, че “GIF” поддържа максимум 8-битови изображения.

обратно към навигационното меню

Премахване на шум и разликово кодиране

“LZW” методът дава отлични резултати при компресирането на изображения с един, осем и 24 бита на отчет. Ефективността на метода обаче пада при работа със зашумени изображения. Следователно една от основните задачи при този алгоритъм е да се премахне шумът или да се намали до приемлив минимум. Един от методите за това е да се нулират една или две от битовите равнини, носещи най-малко полезна информация. Въпреки че това е ефективен метод, той не е за предпочитане. Вместо него се използва друг, наречен разликово кодиране. Идеята му е да представи зашумените пиксели или такива, които се кодират трудно, по начин, улесняващ процеса на кодирането. Използва се фактът, че при многотонови изображения два съседни пиксела се различават съвсем слабо по стойност. Така, ако се замени стойността на пиксел с разликата от стойността на същия пиксел и някой съседен, би се намалило количеството информация, без да се губят полезни данни. Следва да се има предвид, че при "RGB” модела стойностите на трите цвята трябва да се кодират разликово поотделно, а не сумарно, тоест за един пиксел ще имаме три разликови стойности, а не една. Това кодиране най-често се използва по хоризонталните редове за сканиране, но се среща и вертикално. Който и от двата метода да се използва, едно е сигурно – изображения, минали през разликово кодиране, се компресират много по-ефективно чрез “LZW”, отколкото тези, които не са подложени на такова кодиране.

обратно към навигационното меню

Вариации на “LZW” алгоритъма

Съществуват няколко вариации на “LZW” алгоритъма, които подобряват неговата ефективност в някои приложения. Една от често използваните включва индексни указатели, които са различни по дължина, като започват от 9 и стигат до 12-13 бита. Когато се запълни дадена дължина на индексния указател, просто се добавя още един бит към него за увеличаване на точността.

Друга популярна вариация на “LZW” включва постоянно наблюдение върху процеса на компресия, следейки за падане на ефективността. Ако се установи такъв спад, последно използваните фрази от библиотеката се изтриват, като се прави място за нови фрази, или евентуално се изтрива цялата библиотека и се пресъздава наново.

Вариантът, наречен “LZMW”, създава фрази, като свързва две такива вместо текущата фраза и следващия символ. Така по-бързо се изграждат по-дългите стрингове, но се усложнява структурата на данните в библиотеката.

Въпреки че “LZW” алгоритъмът е прост, неговото ефективно прилагане е свързано с важни решения като това кои фрази да се изтрият от библиотеката, за да се заменят с други, или дори това каква структура да се използва за търсене в библиотеката при кодиране – хеш функции или дървовидна структура. Вариациите върху стандартния “LZW” алгоритъм са по-често срещани дори от самия оригинал. Например форматите “TIFF” и “GIF” използват стандартните функции на “LZW” – “Clear code” ( изтрива библиотеката ), “EOF” ( край на файла ) и лимит от 12 бита на кодиран символ, но “GIF” третира всяка стойност на пиксел като отделен символ. Оттук следва, че размерът на азбуката, началният брой битове за компресиран символ и стойностите на “Clear” и “EOF” ще варират в зависимост от броя битове на пиксел на изображението, което се компресира. При “GIF” компресираните кодове се съхраняват, като първо е най-младшият бит, тоест когато два кода са в един байт, първият код е в по-младшите битове, а ако кодът е по-голям от един байт, най-младшият му разряд е в началните байтове. При “TIFF” нещата стоят по друг начин. Винаги се четат 8-битови входни символи от некомпресирани данни без значение от броя битове на пиксел, като най-старшият бит е първи в организацията на байта. Има малък проблем при тази вариация на “LZW” – броят битове за компресиран код трябва да се увеличава по-рано от нужното. Например ако преминаваме от 9 към 10 бита, това става след регистриране на код 511, а не на 512, което може да доведе до загуба на 1 бит.

обратно към навигационното меню

"CCITT" - Хъфман кодиране

Този тип беззагубно кодиране се поддържа от много от най-разпространените формати за неподвижни изображения с 1 бит на пиксел. “CCITT (International Telegraph and Telephone Consultative Committee)” е организация за стандартизация, която е развила няколко протокола за пренасяне на черно-бели изображения по телефонни линии и локални мрежи. Тези протоколи се наричат “CCITT T.4” и “T.6”, но са по-известни под имената “CCITT Group 3” и “Group 4” алгоритми за компресия. Понякога вместо “CCITT” се говори за Хъфман кодиране, но това невинаги е правилно. Хъфман кодирането представлява прост алгоритъм за компресия разработен от Дейвид Хъфман през 1952 г., докато едномерното кодиране “CCITT” е само вариация на кода на Хъфман, а другите типове “CCITT” кодиране пък нямат нищо общо с Хъфман кодирането. Алгоритмите “Group 3” и “Group 4” са специално разработени за кодиране на еднобитови изображения. Всички модерни факс машини поддържат “Group 3” компресия. При този алгоритъм компресията и декомпресията са бързи, има добър коефициент на компресия за различни видове документи и в кода се съдържа допълнителна информация за откриване и корекция на грешки при декодиране, без да има нужда от специален хардуер. “Group 4” е наследник на “Group 3” и от тази гледна точка е много по-ефикасен, като намалява наполовина големината на кодираната информация спрямо едномерния “Group 3”. Недостатък е, че хардуерната му реализация е затруднена, но пък за сметка на това осигурява поне толкова бързо кодиране и декодиране, колкото при “Group 3”, а понякога и по-бързо. Основен минус на “Group 4” e, че не съдържа кодовете за откриване и корекция на грешки, тъй като е предназначен изцяло за локални мрежи, следователно не е добър избор за използване в протокол за предаване на изображения. Двата алгоритъма са широко използвани при системи, където се съхраняват големи количества факс документи, за да се спести дисково пространство. От друга страна декомпресията е бърза и могат да бъдат отпечатани или разгледани по всяко време, а също да бъдат пратени по модем или факс, без да има нужда от предварително кодиране. “CCITT” алгоритмите са неадаптивни, тоест алгоритъмът им остава непроменен без значение какво е изображението. Таблицата с кодовете е фиксирана на базата на шаблон, съдържащ както текст, така и графики. “Group 3” нормално достига коефициент на компресия между 5:1 и 8:1 приложен върху стандартен А4 документ с разделителна способност 200 точки на инч. “Group 4” постига двойно по-добри резултати, като достига компресия 15:1 върху същия документ. Поради това, че двата алгоритъма са оптимизирани за печатни и ръкописни документи, би следвало, че други документи, различаващи се радикално по структура от тях, не биха се кодирали ефикасно. Това наистина е така – достигат се максимални коефиценти на компресия от едва 3:1, а понякога компресираният документ става по-голям от оригинала, което е абсолютно недопустимо.

“CCITT” дефинира три алгоритъма за кодиране на черно-бели изображения:

  • едномерен “Group 3” (G31D)
  • двумерен “Group 3” (G32D)
  • двумерен “Group 4” (G42D)

обратно към навигационното меню

Едномерно кодиране “Group 3” (G31D)

“G31D” е вариация на Хъфман компресия. При черно-бяло изображение, съставено от поредици черни и бели пиксели, черните са единици, а белите – нули. “Group 3” алгоритъмът определя дължината на тези поредици в един ред за сканиране и на изхода записва бинарен код с варираща дължина, който показва дължината и цвета на поредицата от пиксели. Поради това, че кодът на изхода е по-къс от този на входа, се получава компресия. Изходните кодове се вземат от предварително дефинирана таблица, съдържаща кодове за различни поредици от черни и бели пиксели. Тази таблица е част от спецификацията на стандарта и се използва както при кодирането, така и при декодирането на данни. Дължината на всеки изходен код е определена статистически от “CCITT”, като е взета предвид средната честота на появяване на бели и черни поредици от пиксели в печатен и ръкописен документ. На най-често срещаните поредици се присвоява най-къс код, докато на другите, не толкова често срещани, остават по-дългите кодове. Максималният размер на една поредица е ограничен от дължината на един ред за сканиране. За кодирането на поредиците се използват два типа кодове – “makeup” и “terminating”. Една кодирана поредица от пиксели се състои от нула или повече “makeup” кода и един “terminating” код. Вторият код отговаря за по-къси поредици, а първият – за по-дълги. Кодовите поредици, които те образуват се различават в зависимост от това дали поредицата е от бели или черни пиксели. Поредици от пиксели с дължина от 0 до 63 се кодират, използвайки един “terminating” код. Следват поредици от 64 до 2623 пиксела, които се кодират с един “makeup” и един “terminating” код. Поредици по-дълги от 2623 пиксела се кодират, използвайки няколко “makeup” кода и един “terminating” код. Ето и няколко примера плюс схема:

  • поредица от 20 черни пиксела се кодира със съответстващия “terminating” код от таблицата. Информацията от 20 бита става 11 бита, което означава коефициент на компресия приблизително 2:1. (a)
  • поредица от 100 бели пиксела се кодира, използвайки “makeup” код за поредица от 64 бели пиксела, последван от “terminating” код за поредица от 36 бели пиксела. Тук 100 бита полезна информация се свеждат до 13 или компресия 7:1. (b)
  • поредица от 8800 черни пиксела се кодира като три “makeup” кода за поредица от 2560 черни пиксела, един “makeup” код за поредица от 1088 черни пиксела и накрая “terminating” код за поредица от 32 черни пиксела. Получава се свиване от 8800 бита на 61 бита и коефициент на компресия 144:1. (c)

При декодирането на данни от типа “Group 3” се използва т методи, които се различават от повечето схеми за декомпресия. Поради варирането на дължината на всяка кодова поредица, се налага кодираната информация да се чете бит по бит до разпознаване на един от двата кода. Това понякога може да се окаже доста продължителен процес. За ускоряването му може да се използва таблица на състоянията и да се обработва кодираната информация байт по байт. Това е най-бързият и ефективен начин за реализация на “CCITT” декодер. Началото на всеки кодиран поток е поредица от бели пиксели, тъй като при нормална печатна и ръкописна страница най-горното поле е бяло, но ако все пак пикселите са черни, то отново се записва последователност за бели пиксели, но тя е с нулева стойност. По време на декодирането се следи цветът на поредицата, която се декодира, защото няма смисъл да се декодира поредица от бели пиксели, а да се сравняват кодовете с таблицата за поредици от черни и обратно.

Дефинират се и няколко специални кода, които се използват за синхронизация в случай че шум смути телефонното предаване. Разпознавайки този специален код, един “CCITT” декодер може да идентифицира проблеми при предаването и да се опита да приложи алгоритъм за възстановяване на данните чрез апроксимация. Кодът “EOL (End Of Line)” е 12-битов и с него стартира всеки ред при “Group 3” предаване. Този код спомага за откриването на началото и респективно края на даден ред за сканиране по време на предаването на изображението. Ако временно сигналът се зашуми, декодерът изхвърля всички данни, които не може да разпознае докато не получи кода “EOL”. След него декодерът започва да приема нормално, като смята, че данните започват от реда след специалния код. Ако му е зададено, декодерът може да замени пропуснатия ред просто с бяла линия. Това не е единственото приложение на този специален код. Декодерът го използва за да следи дължината на редовете за сканиране, а също и за определяне общия броя редове в едно изображение. Ето и как изглежда “EOL” кода:

Повечето факс машини обаче предават данни с "безкрайна дължина ” и тогава декодерът не може да определи колко дълго трябва да бъде изображението. Друг метод за увеличаване на скоростта е да не се предават белите полета след края на текста, тогава факс машината просто довършва листа, без да печата, за да отчете край на страницата. При капсулирането на изображението информацията за големината му се записва в заглавната част и се чете от декодера преди самото декодиране.

Прекратяването на предаването се извършва с друг специален код наречен “RTC (Return To Control)”, който се прикрепя към края на всеки “Group 3” поток. Състои се от 6 “EOL” кода, постъпващи един след друг. Всъщност този код е част от факсимиле протокола, а не от кодираното съобщение. Ето и как изглежда той:

“FILL” не е код, а по скоро поредица от един или няколко нулеви бита, която се появява между кодиран ред от изображението и кодът “EOL” ( но никога в самия кодиран ред ). Тези поредици се използват да увеличат времето за предаване на кодиран ред от изображението до определена дължина. Може да се използват и за изместване на "RTC” кода до запълване на байта.

обратно към навигационното меню

“TIFF” компресия – тип 2

Схемата за компресия тук е много близка до тази при “G31D”. Съществуват и “TIFF” компресии – тип 3 и 4, които напълно съвпадат със спецификациите за “Group 3” и “Group 4”. Разликата между “G31D” и “TIFF” компресия тип – 2, е, че при втората не се използват кодовете “EOL” и "RTC” и точно поради тази причина този метод понякога се среща под името “Group 3, No EOLs”. Също не се използват и “FILL” поредици, освен в случаите за изместване на последния байт в ред от изображението до края му. Тези модификации се въвеждат, защото споменатите кодове не са нужни при четене на данните, записани върху харддиск или дискета. Обикновените “Group 3” декодери не могат да разчитат информацията без тези кодове и отхвърлят тотално кодираните данни или просто ги декодират като поток, тоест не се получава нищо смислено на изхода. Ето как би трябвало да изглежда едно “Group 3” предаване с кодовете “EOL” и "RTC”:

обратно към навигационното меню

Двумерно кодиране “Group 3” (G32D)

При този метод кодирането зависи в голяма степен от предишния ред на изображението. Това е поради факта, че много изображения имат голяма степен на вертикална кохерентност и така, описвайки разликите между два съседни по вертикала редове вместо самите два реда, получаваме по-добра компресия. Първият пиксел от всяка поредица се нарича променящ елемент, като той маркира промяна на цвета в дадения ред от изображението. Позицията на този елемент е твърдо дефинирана като брой пиксели до следващия или предишен такъв елемент. Изходните кодове, които се използват за позициониране, се наричат “READ (Relative Element Address Designate)” кодове. По-късите кодови думи се използват за описание на преходи, които са отдалечени един от друг на по-малко от 4 пиксела. По-дългите кодови думи пък се използват респективно за преходи, лежащи на по-голямо разстояние от променящия елемент. Като цяло двумерното кодиране е по-ефикасно от едномерното, защото се получава голяма двумерна кохерентност, което е добре. Точно тази кохерентност обаче понякога се оказва проблем при кодирането. Ако се получи зашумяване на някой от редовете, това се предава надолу към останалите. Повредени кодирани редове не могат да бъдат вече декодирани и нещо повече –последвалите редове след повредените също не се приемат правилно. За минимизиране на грешката при наличие на шум “G32D” използва променлива, наречена “K” фактор, и кодира двумерно “K-1” редове, последвани от едномерно кодиран ред. При настъпване на грешка се губят само “K-1” редовете. Декодерът ще се синхронизира наново при постъпване на “EOL” код. Типичните стойности за “K” са 2 или 4. Информация, кодирана с “K=4”, излиза като един блок от данни, съдържащ три двумерно кодирани редове, последвани от един едномерно кодиран. Променливата “K” не се ползва при декодирането, вместо това се модифицира “EOL” кодът, който сигнализира на алгоритъма, че при наличие на единица следващият ред е едномерно кодиран, а при наличие на нула – двумерно. Всички други кодове остават непроменени. Единственият случай, когато “K” се използва при декодиране, е ако е нужно възпроизвеждане на предишния едномерно кодиран ред за възстановяване при грешка.

обратно към навигационното меню

Двумерно кодиране “Group 4” (G42D)

Този метод доразвива двумерния “Group 3” и то до такава степен, че изцяло го измества на пазара. Тук няма “EOL” кодове, а променливата “K” може да е безкрайност. Вграденият в “Group 3” код за откриване и корекция на грешки е премахнат, тъй като “G42D” е предназначен изцяло за локални мрежи. Първият кодиран ред при “Group 4” представлява имагинерен ред съдържащ всички бели пиксели. Кодът "RTC” е заменен от ”EOFB (End Of Facsimile Block)” код, който се състои от два подобни на “EOL” кода. “EOFB” всъщност не е част от кодираната информация, а от протокола за предаване. Допуска се запълване с “FILL” след “EOFB” кода до достигане края на байта. Всички тези подобрения и два пъти по-голямата компресия са за сметка на по-усложненото и по-времеемко кодиране. При хардуерно реализиране на двата алгоритъма обаче разликите в скоростта намаляват значително, правейки “Group 4” по-добрия избор.

обратно към навигационното меню

"JPEG" компресия

“JPEG” или “Joint Photographic Experts Group” е организация за стандартизация, създадена през 1987 г., чиито корени тръгват от Международния комитет по стандартизация и “CCITT”. Поради липсата на метод за ефективна компресия на 24-битови изображения от реалния свят новосформираната организация решава да разработи именно такъв алгоритъм и го кръщава “JPEG”. Той има възможност за компресия на изображения от 6 до 24 бита на пиксел, като това става с доста добра скорост и ефективност. Този метод не се състои от един-единствен алгоритъм, а по-скоро е комбинация от няколко, така че да се получи желаният резултат. Поради тази причина с “JPEG” може да се постигнат както много висока компресия и изображения с влошено, но разбираемо, качество, така и висококачествени изображения, които все пак са по-малки от оригинала. Това се дължи и на обстоятелството, че “JPEG” е предимно метод за компресия със загуби, а разгледаните досега бяха беззагубни. При този метод се премахва информация от изображението, която човек не може да забележи с просто око. Взема се предвид, че малки промени в цвета не се забелязват, докато същите в интензитета се открояват. Коефициентът на компресия, който се постига, е в зависимост от съдържанието на кодираната информация. За фотографии може да достигне от 20:1 до 25:1, без да се наблюдава сериозно влошаване на изображението. Могат, разбира се, да се постигнат и по-високи коефициенти на компресия, но това би занижило качеството му. Постигането на 20:1 компресия не само не се отразява видимо на снимката, а и тя заема по-малко пространство върху носителя, както и се намалява времето за предаването й по мрежата. Методът позволява крайният потребител да определи желаното ниво на компресия, чрез параметър, наречен качествен фактор. Той варира от 1 до 100, като при единица се постигат най-големи коефициенти на компресия и респективно изображението изглежда най-зле, а при 100 се постига най-добро изображение за сметка на по-малката компресия. Оптималният качествен фактор варира в зависимост от съдържанието на изображението. Има няколко стъпки, които са препоръчителни при откриване на оптималния качествен фактор:

  • кодира се изображението с качествен фактор 75;
  • ако се наблюдават недопустими дефекти, то качествения фактор се покачва и се кодира отново.
  • ако изображението има приемливо качество, качественият фактор се намалява, така че изображението да е на ръба на допустимото качество. Полученият качествен фактор е оптимален;
  • най-често качествения фактор 75 е оптимален за голяма гама от изображения, така че ако не ви се повтарят горните стъпки, просто го задайте и започнете кодирането.

Трябва да се има предвид, че “JPEG” невинаги е най-подходящият алгоритъм за компресия по следните причини:

  • изображения, съдържащи големи области с еднакъв цвят, не се компресират добре, защото се появяват несъществуващи пиксели с различен цвят, които са лесно забележими;
  • алгоритъмът е бавен, ако се поддържа само софтуерно. Ако се изисква бърза декомпресия, се налага използването на хардуерно базиран “JPEG” декодер;
  • създаването на собствен кодер за “JPEG” компресия е много трудоемко и затова се препоръчва ползването на създадени вече “JPEG” библиотеки;
  • “JPEG” не се поддържа от множество файлови формати.

обратно към навигационното меню

Основи на “JPEG”

Спецификацията на стандарта дефинира само базови операции, които всички приложения използващи “JPEG”, трябва да поддържат. Кодиращата схема е базирана на дескретно косинус преобразуване, което представлява компресия със загуби. Тази схема е ефективна само за компресия на многотонови изображения, при които разликите между два съседни пиксела обикновено са много малки. На практика алгоритъмът се прилага при изображения с поне 5 бита на пиксел, в спецификацията дори се споменава за минимум 8 бита. Изображение с по-малко битове първо трябва да се скалира до 8 бита на пиксел и тогава да се компресира, но резултатът не би бил задоволителен поради големите скокове между два съседни пиксела. Компресията “JPEG” се дели на няколко основни етапа:

  • изображението се трансформира в оптимално цветово пространство;
  • цветовите компоненти се намаляват, като се усредняват групи от пиксели;
  • прилага се дискретно косинус преобразуване на блокове от пиксели, като така се премахва ненужната информация;
  • всеки блок се квантува с “DCT” коефициентите, използвайки теглови коефициенти, съобразени с човешкото око;
  • получените коефициенти се кодират с варираща по дължина дума чрез алгоритъм на Хъфман за премахване на ненужните коефициенти.

В общи линии всичко споменато досега е дадено на следната блок схема за “JPEG” компресия и декомпресия:

обратно към навигационното меню

Трансформация на изображението

“JPEG” алгоритъмът има възможност да кодира изображения, използващи всякакво цветово простраство поради факта, че кодира всеки компонент отделно. Въпреки това най-добри коефициенти на компресия се получават при “YUV” и “YCbCr” цветови пространства. Повечето от информацията, към която човешкото око е най-чувствително, се намира във високите честоти, вариациите на сивото и яркостния компонент “Y”. Другите цветови компонента (Cb,Cr) съдържат информация, към която човешкото око не е толкова чувствително и съответно част от нея може да бъде премахната, без визуално да се наруши качеството на картината. За да се направи сравнение при "RGB”, "HSI” и “CMY” цветовите пространства, полезната информация се разделя поравно между трите компонента, правейки процеса на селектиране на информация за изхвърляне много труден. Следователно и трите компонента ще се кодират с високо качество и ще се получи нисък коефициент на компресия. Изображенията, които използват само вариации на сивото не се нуждаят от преобразуване, тъй като нямат цветово пространство.

обратно към навигационното меню

Намаляване на цветовите компоненти – децимация

Най-лесният начин да се използва по-малката чувствителност на окото към цветовите компоненти е просто да има по-малко пиксели в цветовите канали. Например за изображение 1000х1000 пиксела да се използват 1000х1000 пикела за яркостта, но 500х500 за всеки от цветовите компоненти. Така всеки цветови пиксел покрива площта на два яркостни пиксела. Получава се, че за блокче 2х2 пиксела се съхраняват само 6 стойности на пиксели – 4 яркостни и 2 цветови, вместо 12. Получава се свиване на информацията с цели 50%, без това да има особен визуален ефект върху изображението. Подобни спестявания при конвенционален цветови модел като "RGB” не са възможни, защото всеки един от каналите носи някаква яркостна информация и дори малкото й компресиране е видимо веднага. “JPEG” стандартът позволява няколко възможности за намаляване на цветовите компоненти. Яркостният канал винаги е с пълна разделителна способност, а двата цветови канала обикновено са намалени 2 пъти по хоризонтала, а по вертикала или са намалени 2 пъти, или са в пълна разделителна способност. Тези видове семплиране се наричат “2h1v” и “2h2v”, както и 4:2:2 и 4:2:0.

обратно към навигационното меню

Дискретно косинус преобразуване

Изображението се разделя на блокове, всеки от които е с размери 8х8 пиксела. Върху тези блокове се прилага дискретно косинус преобразуване, което трансформира изображението в “DC” и “AC” коефициенти, като “DC” съдържат средната стойност на блока, а “AC” –интензивността на промените по широчина и височина в него. Калкулацията на коефициентите е доста сложна и де факто това се явява една от най-бавните стъпки в целия “JPEG” алгоритъм. Все пак без нея не може, защото сега нискочестотната и високочестотната информация в изображението е разделена. По този начин може много лесно да се отдели и изхвърли част от високочестотните съставки, без да се губи информация за ниските честоти. Формулата, с която става самото преобразуване е следната ( приема се, че с “A” е означено входното изображение, с “B” изходното, а “N1” и “N2” са съответно ширината и височината на входното изображение ):

обратно към навигационното меню

Квантуване на всеки блок

За да премахне съответна част от информацията, компресорът дели всяка стойност от “DCT” преобразуването на квантуващ коефициент и закръгля резултата до цяло число. Колкото е по-голям квантуващият коефициент, толкова повече данни се губят, защото “DCT” стойността се представя все по-неточно. Всяка от 64-те позиции на блока има свой квантуващ коефициент, като позициите в началото се квантуват по-грубо, а тези по-надолу – по-точно. По-нататък отделните квантуващи таблици се разделят на коефициенти за яркостни и коефициенти за цветови данни, като цветовите се квантуват по-грубо, а яркостните по-точно. Точно в тази стъпка се отразява качественият фактор, зададен от потребителя. Компресорът стартира от вградена в него квантуваща таблица за средно качество и в зависимост от качествения фактор намалява или увеличава всяка стойност в таблицата в обратна пропорционалност на зададения качествен фактор. Използваната таблица за квантуване се записва в компресирания файл, за да може декомпресорът да възстанови “DCT” коефициентите.

обратно към навигационното меню

Кодиране на получените коефициенти

Получените коефициенти съдържат доста излишна информация, която трябва да се отстрани. Компресията на Хъфман беззагубно я премахва и така се получава по-малък обем от данни. Този тип компресия принадлежи на семейството алгоритми с променлива дължината на кодовата дума. Това означава, че отделни символи се заместват с поредици от битове, вариращи по размер. Идеята е символите, които най-често се срещат, да имат най-кратки кодови думи. Например поредицата: "ACDABA ”, в некомпресиран вид тя е с размер 6 байта или 48 бита. Най-често срещаният символ е “A”, следователно се задава “A”=0, “B”=10, “C”=110, “D”=111. Получава се кодирана поредица "01101110100 ”, която е с размер 11 бита, тоест компресия 4:1 спрямо оригинала. Възможно е алгоритъмът да се оптимизира, като се въведе възможност за динамична промяна на кодовете в зависимост от промените в честотата на поява на символите. Това се нарича адаптивно Хъфман кодиране. Разширеното Хъфман кодиране пък дава възможност да се кодират цели групи символи. Едно от разширенията към “JPEG” спецификацията позволява да се извърши аритметично кодиране вместо Хъфман и тогава се получават дори още по-добри коефициенти на компресия. След тази стъпка “JPEG” кодираните данни са готови за предаване по комуникационния канал или капсуловане във файл.

обратно към навигационното меню

Разширение на “JPEG” – част I

Това разширение включва прогресивно предаване на изображението, подобрени коефициенти на компресия, използвайки аритметично кодиране и схема за беззагубна компресия. Повечето от тези нововъведения не са нужни на по-голямата част от потребителите на “JPEG” и затова са дефинирани като незадължителни за поддръжка.

обратно към навигационното меню

Прогресивно предаване на изображението

Разширение било разработено за приложения, които приемат и изобразяват получените данни в реално време, а основните функции на стандарта “JPEG” позволявали визуализация само след като е получено и декодирано цялото изображение. Използването на конвенционален метод за изобразяване на първите няколко реда също не е вариант, защото ако изображението е кодирано презредово, ще са нужни поне 50% от него, за да се изобрази нещо, което би донесло полезна информация на потребителя. Прогресивният метод на предаване позволява изображението да бъде предавано на пластове, а не на редове, но вместо да се предава всяка битова равнина или цветови канал в една последователност, се изпраща последователност от изображения, изградени на базата на апроксимации от оригиналното изображение. Първото предаване осигурява слабо акуратно представяне под формата на нискокачествено “JPEG” изображение. С всяко следващо предаване качеството му се подобрява до достигане на оригиналния качествен фактор, зададен при компресирането. Едно от ограниченията при този метод, е че всяко предаване задължително се състои от цялостно “JPEG” изображение макар и с ниско качество, което означава, че за всяко предаване се прави пълен декомпресиращ цикъл, а при нормалните скорости на предаване при “JPEG” това ще рече, че има нужда от много бърз “JPEG” декодер за ефективно използване на метода за прогресивно предаване на изображения.

обратно към навигационното меню

Аритметично кодиране

Аритметичният кодер има за вход поредица от символи, от които на изхода излиза рационално число в интервала (0;1). Нека “N” е броят входни символи, а самите те да са “x1, x2,...xN”. С “P1, P2,...PN” се означава вероятността за появата на всеки един от символите. Всяка стъпка от процеса е ограничена за даден интервал [y, y+R]:

I 1 = [y, y + P 1R)

I 2 = [y + P 1R, y + P 1R + P 2R)

...................................

...................................

...................................

I_N = \left[y + \sum^{N-1}_{i=1} P_i R, \ y + R \right)

Така определена поредица от входни символи винаги изкарва точно определен изходен код, който в последствие може да бъде декодиран. По теоремата на Шанон Фенон се получава тотална ентропия на оригинала, което означава, че аритметичното кодиране е най-оптималното ентропийно кодиране. Използването му вместо Хъфман намалява с още 10 до 15% големината на изходните данни, без това да води до загуби в качеството. Въпреки тези плюсове аритметичното кодиране има и някои недостатъци:

  • не всички “JPEG” декодери поддържат аритметично кодиране;
  • алгоритъмът на аритметичното кодиране е по-бавен в сравнение с Хъфман;
  • алгоритъмът за това кодиране е собственост на "IBM” и “AT&T”, което значи, че е нужен лиценз за ползването му.

обратно към навигационното меню

Беззагубна “JPEG” компресия

Стандартният “JPEG” алгоритъм за компресия е със загуби и дори задаването на качествен фактор 100 не означава, че е постигната беззагубна компресия. Това се дължи на “DCT” преобразуването, което винаги внася загуби от закръгляне на коефициентите до цели числа. Отделно би могло да се спести малко от компресията в стъпките за намаляване на цветовите компоненти и квантуването, но това не само няма да доведе до беззагубно кодиране, а би се получил един доста неефикасен начин за компресия със загуби.

В разширение I на стандарта “JPEG” се предлага съвсем отделен алгоритъм за беззагубно кодиране. Той не използва “DCT” преобразуване, а двумерна разликова импулсно кодова модулация. Основната идея, е че стойността на пиксела се комбинира със стойностите на до три съседни пиксели за формиране на предсказваща стойност, която в последствие се изважда от оригиналната стойност на пиксела. Когато се обработи цялото изображение, предсказващите стойности се компресират чрез Хъфман или бинарно аритметично ентропийно кодиране описано в стандарта “JPEG”. Този метод на беззагубна компресия работи с изображения от 2 до 16 бита на пиксел, но се представя най-добре, когато битовете са повече от 6. За такива изображения обикновено се достига коефициент на компресия 2:1.

обратно към навигационното меню

Разширение “JPEG” – част II

То включва възможност за задаване на променливи коефициенти на квантуване, да се избира само определен регион от изображението, с който да продължат операциите по подобряване на качеството му. Включена е и възможност за разделяне на дадено изображение на няколко по-малки за по-лесно буфериране.

обратно към навигационното меню

Променливи коефициенти на квантуване

Променливите коефициенти на квантуване позволяват скалиране на квантуващите коефициенти по време на процеса на компресия. В началото на всеки 8х8 блок се поставя скалиращ коефициент за дадения блок, с който се умножават всички стойности в таблицата. Получените в последствие квантувани стойности могат да бъдат променяни. Променливите коефициенти на квантуване позволяват да бъдат променени характеристиките на изображението, така че то да отговаря на зададен модел. Скалиращите коефициенти могат да се променят многократно и в процеса на декодиране за осигуряване на оптимално качествено изображение на изхода, както и за регулиране на количеството изходни данни.

обратно към навигационното меню

Избор на регион от изображението с цел подобряване на качеството

Това нововъведение подобрява разделителната способност и детайлността на определен регион от изображението. “JPEG” позволява три типа селектиране на регион – йерархично, прогресивно и компонентно. Всеки един от тях се различава от останалите по ефективност, сложност на реализация и нужна памет:

  • йерархичното селектиране позволява на регион от кадър да бъде "подобрен ” само от следващия отличаващ се кадър в йерархичната поредица;
  • прогресивното селектиране позволява по-големи разделителни способности за нулеви и ненулеви “DCT” коефициенти в определен регион от кадъра;
  • компонентното селектиране позволява на регион от кадър да съдържа по-малко цветове, отколкото са дефинирани в заглавната част.

обратно към навигационното меню

Разделяне на изображението на подизображения

Този процес на разделяне позволява по-лесно буфериране на данните от изображението в паметта, по-бърз случаен достъп до всяка част от изображението и съхранение на изображения по-големи от 64 Kx64K. Стандартът “JPEG” поддържа три вида разделяне на подизображения – просто, пирамидално и композитно:

  • простото разделяне се състои в делене на изображението на 2 или повече фиксирани по големина изображения. Те се кодират от ляво на дясно и от горе на долу, като не се припокриват. Всички части трябва да имат еднакви размери и да се кодират, използвайки едни и същи процеси;
  • пирамидалното разделяне също дели изображението на парчета, но всяко от тях е разделено допълнително, използвайки различни нива на разделителна способност. Обикновено се прилага процесът, наречен вътрешно разделяне, където всяка част се кодира в един и същ поток от данни. Възможно е и ползването на външно разделяне, при което всяка част се кодира в отделен поток. Това би довело до по-бърз достъп до данните от изображението, по-лесно прилагане на криптиращи алгоритми и подобрена съвместимост с определени “JPEG” декодери;
  • композитното разделяне позволява няколко части с различни разделителни способности да бъдат съхранени и изобразени като мозайка. Всяка част се кодира отделно и може да бъде комбинирана с други части, без да има нужда от повторно семплиране [3, 5].

обратно към навигационното меню

Файлови формати за неподвижни изображения

"Microsoft Windows Bitmap (BMP)"

тип на изображението

растерно

брой битове на пиксел

1, 4, 8, 16, 24 и 32 бита

компресия

некомпресирано или “RLE”

максимален размер на изображението

32Кх32К и 2Gx2G

създател

“Microsoft Corporation”

поддържани платформи

“Windows”, “OS/2”, “MS-DOS”

“BMP” е базисният графичен формат за операционната система “Windows”, като има възможност да съхранява всякакъв вид растерни изображения. Поддържа се задължително от всички приложения, разработени за тази операционна система. Форматът е широко разпространен и в операционните системи “MS-DOS” и “OS/2”.

Първата версия на “BMP” – 1.0 била много опростена. Имала фиксирана палитра от цветове, не поддържала компресия и работела само с най-разпространените за онова време видео карти – "CGA”, “EGA”, “Hercules” и т.н. Често тази версия на формата се среща под името “DDB”. Във версия 2.0 се добавя възможност за избиране на цветова палитра. При съхранение на изображението в паметта, то е известно като “DIB”, а ако се запише в изходен файл – като “BMP”. Така всъщност излиза, че “DIB” и “BMP” са две различни наименования на едно и също нещо. Най-новата версия на формата е 4.0 и нововъведенията в нея са разгледани подробно по-надолу. Форматът “BMP” е хардуерно зависим и поддържа изображения до 32 бита на пиксел. Опростената му структура го прави идеален както за цветни, така и за черно-бели изображения, стига големината на файла да не е важен фактор. Въпреки че форматът поддържа “RLE” беззагубна компресия, тя се използва много рядко и именно поради тази причина “BMP” е най-широко разпространен в некомпресиран вид.

обратно към навигационното меню

Файлова структура

При версия 1.0 файлът се състоял само от две части – заглавна и полезни данни. Нямало място за цветова палитра, тъй като тя винаги била една и съща. Също липсвала и възможност за компресия:

заглавна част на файла

полезни данни

С развитието на формата до версия 4.0 се добавят още две части – палитра и заглавна част на полезната информация. От 4-те части само палитрата може евентуално да липсва, другите са задължителни. Големината на заглавната част на файла е 14 байта и е почти идентична на тази във версия 1.0:

заглавна част на файла

заглавна част на полезната информация

палитра

полезни данни

обратно към навигационното меню

“BMP”, версия 1.0 – “DDB”

Заглавната част на файла е от 10 байта и има следния вид:

typedef struct _Win1xHeader {
WORD Type; /* идентификатор за типа на файла (винаги 0) */
WORD Width; /* широчина на изображението в пиксели */
WORD Height; /* височина на изображението в редове */
WORD ByteWidth; /* широчина на изображението в байтове */
BYTE Planes; /* брой цветови равнини ( винаги 1 ) */
BYTE BitsPerPixel; /* брой битове на пиксел (1, 4 или 8 ) */
} WIN1XHEADER;

След тази част веднага следва некомпресираната полезна информация. Всеки пиксел се възпроизвежда посредством индексна стойност, записана във фиксираната палитра на “Windows”. Наличието на допълване в някой ред се установява, като сравним изчислената стойност за широчината на реда и моментната такава, записана в полето “ByteWidth”.

обратно към навигационното меню

“BMP”, версия 2.0

Всички версии на “BMP” формата след версия 1.0 започват с една и съща заглавна част на файла с размер 14 байта:

typedef struct _WinBMPFileHeader {
WORD FileType; /* тип на файла, винаги 4D42h ( "BM ” ) */
DWORD FileSize; /* големина на файла в байтове ( съдържа стойност само ако файлът е компресиран, иначе е нула*/
WORD Reserved1; /* винаги 0 ( използва се, когато се чете от паметта ) */
WORD Reserved2; /* винаги 0 ( използва се, когато се чете от паметта ) */
DWORD BitmapOffset; /* отместване до началото на полезните данни в байтове */
} WINBMPFILEHEADER;  

След тази заглавна част следва друга, но на полезните данни. Тя съдържа специфична информация за данните в изображението. Големината й е 12 байта и има следния формат:

typedef struct _Win2xBitmapHeader {
DWORD Size; /* големина на заглавната част за полезните данни в байтове ( винаги стойността е 12 ) */
SHORT Width; /* широчина на изображението в пиксели */
SHORT Height; /* височина на изображението в пиксели ( ако е положително число, редовете в изображението са ориентирани от долу на горе, ако е отрицателно – от горе на долу ) */
WORD Planes; /* брой цветови равнини ( винаги 1 ) */
WORD BitsPerPixel; /* брой битове на пиксел (1, 4, 8 или 24) */
} WIN2XBITMAPHEADER;

Следва структурата на цветовата палитра. Тя присъства, ако имаме 1, 4 или 8 бита на пиксел. Тези с 24 бита на пиксел не ползват палитра. Всеки елемент от палитрата е с големина 3 байта и има следната структура:

typedef struct _Win2xPaletteElement {
BYTE Blue; /* син компонент за пиксел ( от 0 до 255 ) */
BYTE Green; /* зелен компонент за пиксел ( от 0 до 255 ) */
BYTE Red; /* червен компонент за пиксел ( от 0 до 255 ) */
} WIN2XPALETTEELEMENT;

Големината на палитрата се изчислява на базата на стойността, записана в полето “BitsPerPixel”. Съответно палитрата има 2, 16, 256 или 0 елемента за следните стойности на “BitsPerPixel” – 1, 4, 8 и 24. За да се открие дали в дадена структура съществува палитра, е достатъчно да се изчисли броя байтове между заглавната част за полезната информация и самата полезна информация и да се раздели тази стойност на големината на един елемент от палитрата. Съответно ако броят елементи там е нула, няма палитра в структурата, в противен случай след изчислението се получава броя елементи в цветовата палитра.

обратно към навигационното меню

“BMP”, версия 3.0

Структурата на заглавната част на файла е същата, както във версия 2.0, затова няма да се повтаря, а ще се обърне повече внимание на заглавната част за полезната информация, която е разширена в сравнение с тази от предишната версия и заема 40 байта, съдържайки 6 допълнителни полета:

typedef struct _Win3xBitmapHeader {
DWORD Size; /* големина на заглавната част за полезните данни в байтове ( винаги стойността е 40) */
LONG Width; /* широчина на изображението в пиксели */
LONG Height; /* височина на изображението в пиксели ( ако е положително число, редовете в изображението са ориентирани от долу на горе, ако е отрицателно – от горе на долу ) */
WORD Planes; /* брой цветови равнини ( винаги 1 ) */
WORD BitsPerPixel; /* брой битове на пиксел (1, 4, 8 или 24) */

/* следват новодобавените полета във версия 3.0 */

DWORD Compression; /* използвани методи за компресия ( за некомпресирани изображения е 0, за “RLE” 8-битова беззагубна компресия е 1 и за “RLE” 4-битова беззагубна компресия е 2 ) */
DWORD SizeOfBitmap; /* големина на изображението в байтов e ( стойността на това поле е 0, ако изображението не е компресирано ) */
LONG HorzResolution; /* хоризонтална разделителна способност в пиксели на метър */
LONG VertResolution; /* вертикална разделителна способност в пиксели на метър */
DWORD ColorsUsed; /* брой цветове в изображението ( брой цветове в палитрата; ако е нула и полето “BitsPerPixel” има стойност по-малка от 16 бита, това означава, че се използва максималният позволен брой елементи в палитрата ) */
DWORD ColorsImportant; /* минимален брой важни цветове (oпределят се по броя появявания в изображението, тоест тези, които се срещат най-често, са и най-важни ) */
} WIN3XBITMAPHEADER;

Полето “ColorsImportant” е едно от нововъведенията във версия 3.0 на “BMP” и играе важна роля при визуализирането на изображението на графичен адаптер, който поддържа по-малко цветове, отколкото има в самото изображение. Например за едно 8-битово изображение със 142 цвята може само около 12 от тях да съставят най-важната информация в изображението, следователно след тяхното индентифициране като важни цветове е възможно по-точно изобразяване на изображението, използвайки графичен адаптер, поддържащ само 16 цвята. Най-важните цветове винаги се съхраняват в първите елементи на цветовата палитра.

Вървейки по гореописаната структура, се стига до цветовата палитра, която е идентична с тази при версия 2.0, но е добавен един байт за отместване и така общата големина на палитрата става 4 байта със следната структура:

typedef struct _Win3xPaletteElement {
BYTE Blue; /* син компонент за пиксел ( от 0 до 255 ) */
BYTE Green; /* зелен компонент за пиксел ( от 0 до 255 ) */
BYTE Red; /* червен компонент за пиксел ( от 0 до 255 ) */
BYTE Reserved; /* отместване до края на четен байт (винаги 0) */
} WIN3XPALETTEELEMENT;  

обратно към навигационното меню

“BMP”, версия 3.0 за “Windows NT”

В тази вариация на версия 3.0 заглавната част на полезната информация по структура е същата, както при стандартната версия 3.0, но полето “Compression” има още една възможна стойност – 3, която показва, че е използвано побитово кодиране. Това е въведено, защото ако изображението съдържа 16 или 32 бита на пиксел, единствената компресия, която се поддържа, е именно побитова. При нея се появяват 3 нови полета в цветовата палитра:

typedef _WinNtBitfieldsMasks {
DWORD RedMask; /* показва кои битове в даден пиксел отговарят на червения компонент */
DWORD GreenMask; /* показва кои битове в даден пиксел отговарят на зеления компонент */
DWORD BlueMask; /* показва кои битове в даден пиксел отговарят на синия компонент */
} WINNTBITFIELDSMASKS;
 

Битовете в пиксел са подредени от най-старшия към най-млашия. За 16-битови изображения често се използва форматът "RGB565” за указване на 5 бита червени и сини стойности и 6 бита за зелени:

RedMask = 0xF8000000; /* 1111 1000 0000 0000 0000 0000 0000 0000 */
GreenMask = 0x07E00000; /* 0000 0111 1110 0000 0000 0000 0000 0000 */
BlueMask = 0x001F0000; /* 0000 0000 0001 1111 0000 0000 0000 0000 */

За 32-битови изображения може да се ползва форматът "RGB101010”, при който са отделени по 10 бита за всеки компонент:

RedMask = 0xFFC00000; /* 1111 1111 1100 0000 0000 0000 0000 0000 */
GreenMask = 0x003FF000; /* 0000 0000 0011 1111 1111 0000 0000 0000 */
BlueMask = 0x00000FFC; /* 0000 0000 0000 0000 0000 1111 1111 1100 */  

обратно към навигационното меню

“BMP”, версия 4.0

Структурата започва с добре известната от версия 2.0 и 3.0 заглавна част на файла с големина 14 байта. Заглавната част за полезната информация е значително разширена и съдържа 17 допълнителни полета, като цялата е с големина 108 байта и има следната структура:

typedef struct _Win4xBitmapHeader {
DWORD Size; /* големина на заглавната част за полезните данни в байтове ( винаги стойността е 108 ) */
LONG Width; /* широчина на изображението в пиксели */
LONG Height; /* височина на изображението в пиксели ( ако е положително число, редовете в изображението са ориентирани от долу на горе, ако е отрицателно – от горе на долу ) */
WORD Planes; /* брой цветови равнини ( винаги 1 ) */
WORD BitsPerPixel; /* брой битове на пиксел (1, 4, 8, 16, 24 или 32 ) */
DWORD Compression; /* използвани методи за компресия ( за некомпресирани изображения е 0, за “RLE” 8-битова беззагубна компресия е 1, за “RLE” 4-битова беззагубна компресия е 2 и за побитово кодиране е 3 ) */
DWORD SizeOfBitmap; /* големина на изображението в байтов e ( стойността на това поле е 0, ако изображението не е компресирано ) */
LONG HorzResolution; /* хоризонтална разделителна способност в пиксели на метър */
LONG VertResolution; /* вертикална разделителна способност в пиксели на метър */
DWORD ColorsUsed; /* брой цветове в изображението ( брой цветове в палитрата; ако е нула и полето “BitsPerPixel” има стойност по-малка от 16 бита, това означава, че се използва максималният позволен брой елементи в палитрата ) */
DWORD ColorsImportant; /* минимален брой важни цветове (o пределят се по броя появявания в изображението, тоест тези, които се срещат най-често, са и най-важни ) */

/* следват добавените във версия 4.0 полета */

DWORD RedMask; /* показва кои битове в даден пиксел отговарят на червения компонент */
DWORD GreenMask; /* показва кои битове в даден пиксел отговарят на зеления компонент */
DWORD BlueMask; /* показва кои битове в даден пиксел отговарят на синия компонент */
DWORD AlphaMask; /* показва кои битове в даден пиксел отговарят на прозрачния компонент */
DWORD CSType; /* вид на цветовото пространство ( 00 h – калибрирано "RGB”(XYZ); 01h – "RGB”; 02h – “CMYK”) */
LONG RedX; /* X координатата за червената крайна точка ( използва се само ако “CSType=00h”) */
LONG RedY; /* Y координатата за червената крайна точка ( използва се само ако “CSType=00h”) */
LONG RedZ; /* Z координатата за червената крайна точка ( използва се само ако “CSType=00h”) */
LONG GreenX; /* X координатата за зелената крайна точка ( използва се само ако “CSType=00h”) */
LONG GreenY; /* Y координатата за зелената крайна точка ( използва се само ако “CSType=00h”) */
LONG GreenZ; /* Z координатата за зелената крайна точка ( използва се само ако “CSType=00h”) */
LONG BlueX; /* X координатата за синята крайна точка ( използва се само ако “CSType=00h”) */
LONG BlueY; /* Y координатата за синята крайна точка ( използва се само ако “CSType=00h”) */
LONG BlueZ; /* Z координатата за синята крайна точка ( използва се само ако “CSType=00h”) */
DWORD GammaRed; /* координатна стойност на гамата за червеното */
DWORD GammaGreen; /* координатна стойност на гамата за зеленото */
DWORD GammaBlue; /* координатна стойност на гамата за синьото */
} WIN4XBITMAPHEADER;

Всички нововъведени полета са за поддръжка на 16 и 32-битови изображения, както и за цветова съвместимост при визуализация или принтиране на изображението.

обратно към навигационното меню

Цветова палитра

Както се видя в структурите описани досега, цветовата палитра е масив от елементи, които се отнасят до трите основни цвята – червено, зелено и синьо. Всеки пиксел в изображението има една-единствена стойност, която е под формата на индекс в палитрата. Цветовата информация, съхранявана в елемента, към който сочи индексът е де факто цветът на този пиксел. Важно е да се знае, че изображенията с 1, 4 и 8 бита имат цветови палитри, а тези с 16, 24 и 32 бита нямат такива. При 16 и 32-битовите се използват побитови маски вместо цветови палитри. Не трябва да се забравя, че палитрите биват 3 и 4-байтови. Най-лесният начин да се установи размера й е да се провери големината на заглавната част за полезните данни. Ако тя е 12 байта, следва че се работи с версия 2.0 на “BMP” формата и палитрата е 3-байтова, но ако е 40 или 108 байта, със сигурност цветовата палитра е с размер 4 байта.

обратно към навигационното меню

Видове “BMP” файлове

Всяка нова версия на “BMP” формата добавя нова информация към заглавната част за полезните данни. В някои версии дори се изменя големината на цветовата палитра, както и се добавят все по-нови възможности. За съжаление в заглавната част на файла не е включено поле, което да показва с коя версия на формата работим. Независимо от версията всички файлове имат едно и също разширение – ".BMP”. Явно е, че по него не може да се определи версията. За тази цел се използва кратък алгоритъм – започва се от полето “FileType”, ако стойността му е “424Dh”, това означава, че изображението е създадено или под “Windows”, или под “OS/2”. Ако пък стойността е “4142h”, със сигурност се работи с масив от изображения, създаден под “OS/2”. В алгоритъма следва да се прочете полето “Size”, за да се определи версията на файла, а вариантите са както следва – 12 байта за версия “Windows 2.0 ” и “OS/2 1.0”; 40 байта за версия “Windows 3.0” и “Windows NT”; от 12 до 64 байта за версия “OS/2 2.0” и 108 байта за версия “Windows 4.0”. Разпознаването на версиите за “Windows NT” става по стойността на полето “Compression”, която винаги е 3. Също трябва да се отчете, че единствената разлика между “Windows 2.0” и “OS/2 1.0” форматите е типът на полетата “Width” и “Height”, като в първия случай те са “signed short”, а във втория – “unsigned short”.

обратно към навигационното меню

Полезни данни и компресия

Некомпресираните данни представляват серии от стойности или на индекси от цветовата палитра, или на същински цветове от "RGB” пространството. Пикселите се пакетират в байтове и се подреждат по редове. Всеки ред трябва да завършва кратен на 4 байта, така че е възможно да се наложи допълване с един, два или три байта на ред, за да се спази това условие. Редовете се съхраняват от долу нагоре, ако стойността на полето “Height” e положителна, и от горе на долу, ако е отрицателна. Първият вариант е по-често срещан, тъй като при другия не е възможна компресия. Монохромните изображения съдържат един бит на пиксел и респективно осем пиксела в един байт. Това им отрежда цветова палитра с два елемента. Ако при четене се вземе решение за игнориране на палитрата, всички единици се приемат за цвета на обектите, а всички нули за цвета на фона. Изображенията с 4 бита на пиксел се пакетират по 2 пиксела в един байт, като най-старшият бит е най-отпред. Броят елементи в палитрата е 16. 8-битовите изображения пък се пакетират по един пиксел в байт с 256 елементи в палитрата. При “Windows NT” 16-битовите изображения се пакетират в два байта, като организацията на битовите полета се дефинира от стойностите на полетата “RedMask”, “GreenMask” и “BlueMask”. Най-често използваните маски са "RGB555” и "RGB565”. Във версия 4.0 на “BMP” формата 16 и 32-битовите изображения се пакетират в 4 байта, като най-често използваните маски са "RGB888” и "RGB101010”. 24-битовите изображения се пакетират в 3 байта.

Форматът “BMP” поддържа “RLE” схема на компресиране с 8 и 4 бита и тъй като този алгоритъм е байтово базиран, не може да се използва за изображения с 1, 16, 24 или 32 бита на пиксел, защото там липсват дълги поредици от еднакви стойности, нужни за ефективното кодиране с “RLE”. Използва се схемата с две стойности, като първата показва броя повторения на дадена стойност, а вторият – самата стойност. 8-битовият “RLE” алгоритъм може да кодира до 255 еднакви последователни стойности в един пакет. Така кодирана поредица "05 18 ” би се декодирала на пет пиксела със стойност 18. Когато един ред от изображението не съдържа достатъчно еднакви последователни пиксели за постигане на задоволителен коефициент на компресия, този ред от пиксели може да се запише директно без кодиране. В този случай първият байт от кодирания пакет е нула, за да покаже, че следва некодирана поредица, а вторият започва с броя некодирани символи, които следват:

Кодирани пакети

Декодирани данни

05 10

10 10 10 10 10

00 05 23 65 34 56 45

23 65 34 56 45

0A 0A

0A 0A 0A 0A 0A 0A 0A 0A 0A 0A

00 04 46 57 68 79

46 57 68 79

В “RLE” пакетите могат да бъдат открити и 3 специфични маркера, всеки от които започва с нулев байт. Вторият байт в пакета указва типа на маркера. Основната информация, която носят тези маркери, е за позициониране, свързвано с декодирането, и не съдържат никаква полезна информация. Първият от тези маркери указва края на ред от изображението, като и двата му байта са нулеви – “00 00”. Кодираната информация, която постъпва след такъв маркер, вече се смята от следващия ред. Ако съответно липсва този маркер, пикселите автоматично се преместват от единия на другия ред. Той се използва само когато се изисква редът да свърши на точно определено от нас място, а не където свършва всъщност. Така например ако маркерът постъпи по средата на реда, всички останали пиксели от него се игнорират. Вторият маркер се използва за указване края на изображението, предава се в последния “RLE” пакет и има следния вид – “00 01”. Последният от трите специални маркери се нарича маркер за отместване или също е известен като делта или векторен код. Той е с големина 4 байта, като първите му 2 байта винаги имат стойности – “00 02”. Другите два байта указват отместване на пиксел от позицията, в която се намира в момента курсорът, като стойността на “X” указва броя пиксели напред в реда, а стойността на “Y” – броя редове надолу. Този маркер посочва позицията в изображението, където следващата декодирана поредица трябва да бъде записана. Например маркер със стойност “00 02 05 03” означава отместване на курсора 5 пиксела напред в реда и 3 реда надолу, където следва записване на декодиращата се в момента поредица от пиксели. Маркерите за отместване се използват, когато изображението съдържа много пиксели "без значение ”, например ако имаме маска, вместо да кодираме всички пиксели, се кодират само тези, които носят някаква информация. В последствие при декодирането се ползват тези делта кодове за прескачане на ненужните пиксели и позициониране на курсора там, където започва маската. Резюмирани, трите маркера изглеждат така:

00 00 - край на ред от изображението
00 01 - край на изображението
00 02 XX YY - отместване на курсора на определена позиция

Следва нагледен пример за декодиране на 8-битов поток от данни. Всяка от стойностите е 8-битов индекс, сочещ към цветовата палитра, а не реален цвят:

Кодирани байтове

Описание на декодирането

Декодирани байтове

04 16

4 байта със стойност 16

16 16 16 16

08 45

8 байта със стойност 45

45 45 45 45 45 45 45 45

00 00

край на реда

няма

00 02 04 02

Преместване на курсора 4 пиксела напред в реда и два реда по-надолу

няма

03 E4

3 байта със стойност E4

E4 E4 E4

00 03 12 A4 46 00

3 байта некодирани данни

12 A4 46

00 00

край на реда

няма

00 01

край на изображението

няма

4-битовият алгоритъм на “RLE” много прилича на този с 8 бита. Всички маркери са същите, като единствената разлика е, че два пиксела се пакетират в един байт. Така кодирана, информация от вида "07 48 ” би се декодирала така – "04 08 04 08 04 08 04 ”. Това разбира се не значи, че с този алгоритъм не могат да се кодират еднакви пиксели. Просто тогава кодът изглежда например така – “0C 99”. Следва примерно декодиране на 4-битов кодиран поток от данни, като всички стойности са 4 –битови индекси от цветовата палитра, а не реални цветове:

Кодирани байтове

Описание на декодирането

Декодирани байтове

04 16

4 пиксела, редуващи се 1 и 6

1 6 1 6

08 44

8 пиксела, редуващи се 4 и 4

4 4 4 4 4 4 4 4

00 00

край на реда

няма

00 02 04 02

Преместване на курсора 4 пиксела напред в реда и два реда по-надолу

няма

03 E4

8 пиксела, редуващи се E и 4

E 4 E

00 06 12 A4 46 00

6 пиксела некодирана информация

1 2 A 4 4 6

00 00

край на реда

няма

00 01

край на изображението

няма

Ето и резюмирани основните характеристики на “BMP” формата:

битове на пиксел

големина на пиксела

компресия

цветова палитра

цветови маски

1 бит

1 бит

0

да

не

4 бита

4 бита

0,2

да

не

8 бита

1 байт

0,1

да

не

16 бита

4 байта

3

не

да

24 бита

3 байта

0

не

не

32 бита

4 байта

3

не

да

обратно към навигационното меню

"Graphics Interchange Format (GIF)"

тип на изображението

растерно

брой битове на пиксел

от 1 до 8 бита

компресия

“LZW”

максимален размер на изображението

64Kx64K

създател

“Compuserve Inc.”

поддържани платформи

“Windows”, “Macintosh”, “MS-DOS”, “UNIX”

Използва се за съхраняване на няколко изображения в един файл за размяна между различните платформи. По-голямата част от изображенията съдържат 16 или 256 цвята, което осигурява сравнително добро качество. Изображенията, използващи гамата на сивото, също са много често срещани при този формат, докато монохромните изображения са рядкост. Предимство на “GIF” формата е, че не е разработен специално за дадено приложение или платформа, но за сметка на това се поддържа от голяма част от тях, което го прави изключително удобен за прехвърляне на изображения помежду им.

обратно към навигационното меню

Файлова структура

Структурата на “GIF” формата се различава от тази на много други растерни изображения главно по това, че той е базиран на поточно предаване и визуализиране. Състои се от серии от пакети с данни, наречени блокове, към които се добавя и протокол, свързан с допълнителната информация. Поради тази си структура се налага “GIF” формата да се чете като поток от данни. Различните блокове и подблокове от данни могат да бъдат открити навсякъде във файла. Тази неизвестност прави капсулирането им под формата на “C” структури неимоверно трудно. Съществуват няколко категории блокове. Например блокът “Graphics Control Extension” е от категорията “Graphics Control”, a блоковете “Plain Text Extension” и “Local Image Descriptor” са от категорията “Graphic Rendering”. Полезните данни от изображението спадат към категорията “Image Data”, а блоковете “Comment Extension” и “Application Extension” са от “Special Purpose”. Всички тези блокове освен информация могат да съдържат и подблокове. Подблокът започва с байт брояч, чиято максимална стойност е 255 и указва броя байтове с данни, които следват след него. Поредица от подблокове може да бъде прекъсната от байт брояч със стойност нула. Както вече е известно, “GIF” форматът може да съхранява данни от 1 до 8 бита на пиксел. Изображенията винаги използват "RGB” цветовото пространство и цветова палитра. Форматът има и възможност за запис на няколко изображения в един файл, но тя рядко се използва. Алгоритъмът за компресия винаги е “LZW”. Съществуват две версии на “GIF” формата, като и двете са широко разпространени. Оригиналната версия се нарича “GIF87a”, а по-новата – “GIF89a”. В нея се добавя възможност за запис на текст и графика в един и същи файл. За приложения, работещи с “GIF” формата, е абсолютно задължителна поддръжката и на двете версии.

обратно към навигационното меню

“GIF87a”

Това е първата и оригинална версия на “GIF” формата, представена през май 1987 г. Неговата структура изглеждала по следния начин:

Всеки файл задължително започва със заглавна част последвана от “Logical Screen Descriptor”. Следващият блок е опционен и може да го няма – "Глобална цветова палитра ”. Всеки от тези три блока има винаги еднакво отместване спрямо началото на файла. Блокът “Local Image Descriptor” и блокът, съдържащ данните от изображението, са задължителни, докато блокът "Локална цветова палитра ” е само опционен. Последният блок във всеки “GIF” файл се нарича “Terminator character” и обозначава края на “GIF” потока от данни.

обратно към навигационното меню

Заглавна част

Големината й е 6 байта и се използва само за индентификация на файла като “GIF”. Блокът “Logical Screen Descriptor” може да се смята за втора заглавна част и затова двата блока използват подобна структура:

typedef struct _GifHeader {

// полета за заглавната част

BYTE Signature[3]; /* тип на файла (винаги "GIF" – 3 байта) */
BYTE Version[3]; /* версия ("87a" или "89a" – 3 байта) */

// полета в "Logical Screen Descriptor ”

WORD ScreenWidth; /* широчина на екрана в пиксели ( минималната нужна за визуализация на изображението ) */
WORD ScreenHeight; /* височина на екрана в пиксели ( минималната нужна за визуализация на изображението ) */
BYTE Packed; /* информация за екрана и цветовото пространство */
BYTE BackgroundColor; /* индексен цвят на фона ( за пространството, незаето от изображението ) */
BYTE AspectRatio; /* коефициент на формата на пикселите ( широчината на пикселите разделена на височината им ) */
} GIFHEAD;

обратно към навигационното меню

“Logical Screen Descriptor”

Ако графичният адаптер не може да визуализира изображението със зададената разделителна способност, се налага скалиране. Полето “Packed” съдържа 4 подполета ( нулевият бит е най-старшият ):

битове 0-2

големина на глобалната цветова палитра

бит 3

флаг за сортиране на цветовата палитра

битове 4-6

цветова разделителна способност

бит 7

флаг на глобалната цветова палитра

Големината на глобалната цветова палитра всъщност е равна на броя битове за пиксел минус едно. Така например за изображение с 8 бита на пиксел това поле ще има стойност 7. Дори да няма блок "Глобална цветова палитра ”, което означава, че бит 7 е нула, в структурата на “GIF” формата двата бита от “Logical Screen Descriptor” не се влияят от това. Ако бит 7 е единица, тогава записаните в глобалната цветова палитра цветове се сортират в низходящ ред, като се започва от най-често срещания. Правейки това, се улеснява работата на графични карти, поддържащи по-малък брой цветове, отколкото има в изображението, защото така цветовете, които са в началото на глобалната палитра, са най-важните, тоест тези, които подобни карти трябва да изобразят. Флагът за сортиране е валиден само във версия “GIF89a”, иначе е резервиран и винаги е нула. Полето за цветова разделителна способност съдържа броя битове, нужни за оригиналния цвят в цветовата палитра минус едно. Например за изображение, което в оригинал съдържа 8 бита на цвят, тази стойност ще е 7. Ако флагът за глобалната цветова палитра e нула, тоест нямаме този блок в структурата, полето “BackgroundColor” се игнорира. При наличие на нула за полето “AspectRatio” се подразбира, че не е специфициран коефициент на формата на пикселите.

обратно към навигационното меню

Глобална цветова таблица

Този блок не е задължителен. Ако все пак го има, се намира след “Logical Screen Descripor” и се използва за индексиране на цветовете, които се съдържат в изображението, а при липсата му всяко от изображенията във файла разполага със своя локална цветова палитра. Евентуално ако и двете ги няма, се използва стандартна палитра, като се препоръчва първите два цвята в нея да са черно и бяло. Глобалната цветова палитра всъщност е серия от 3 байтови групи, които образуват елементите й. Всяка група съдържа стойности за трите основни цвята – червено, зелено и синьо:

typedef struct _GifColorTable {
BYTE Red; /* стойност на червеното */
BYTE Green; /* стойност на зеленото */
BYTE Blue; /* стойност на синьото */
} GIFCOLORTABLE;

Броят елементи в глобалната цветова палитра винаги е кратен на 2, като максималният им брой е 256. Големината на тази палитра се изчислява, като се използват битове 0,1 и 2 от полето “Packed”.

След трите блока, съдържащи заглавните части и глобалната цветова палитра, следват едно или няколко изображения с техните собствени блокове – “Local Image Descriptor”, "Локална цветова палитра ” ( опционен ) и полезни данни.

обратно към навигационното меню

“Local Image Descriptor”

Винаги е преди блока за полезни данни и има следната структура:

typedef struct _GifImageDescriptor {
BYTE Separator; /* идентифицира блока като “Image Descriptor” ( стойност – “2Ch”) */
WORD Left; /* позиция по Х, откъдето започва изображението ( обикновено е 0 ) */
WORD Top; /* позиция по Y, откъдето започва изображението ( обикновено е 0 ) */
WORD Width; /* широчина на изображението в пиксели */
WORD Height; /* височина на изображението в пиксели */
BYTE Packed; /* информация за изображението и цветовата таблица */
} GIFIMGDESC;

Полето “Packed” съдържа следните 5 подполета ( битът 0 е най-младши ):

бит 0

флаг за локалната цветова палитра

бит 1

флаг "Interlace ”

бит 2

флаг за сортиране

битове 3-4

Резервирани

битове 5-7

големина на елементите в локалната цветова палитра

Ако бит 0 е единица се използва локалната цветова палитра на изображението, а ако е нула – глобалната. Флагът “Interlace” обозначава дали изображението е “interlaced” или “non-interlaced”, като при стойност единица е “interlaced”. Флагът за сортиране показва дали елементите в локалната цветова палитра са подредени по важност, като стойност 1 обозначава сортирана палитра. Този флаг е валиден само във версия “GIF89a” на формата. В по-старата версия е резервиран и винаги е нула. Последното подполе от полето “Packed” указва броя битове на елемент от локалната цветова таблица, но ако бит 0 е нула, то и тези битове (5-7) също са нули.

обратно към навигационното меню

Локална цветова таблица

Ако я има, тя е веднага след “Local Image Descriptor” и преди блока с полезни данни. Структурата на локалните цветови таблици е абсолютно идентична с тази на глобалната – всеки елемент се състои от 3 байтови серии, съдържащи стойности за трите основни цвята – червено, зелено и синьо. Дадена локална цветова таблица отговаря само за изображението, на което принадлежи. Дори да има глобална цветова таблица, изображението ползва локалната си, ако има такава. За едно изображение се позволява най-много една локална цветова таблица.

обратно към навигационното меню

Полезни данни

Форматът “GIF” използва единствено “LZW” компресия, поради тази причина по-нататъшно компресиране на изображението, например със “ZIP”, не би довело до особено допълнително свиване на информация. Поради структурирането на “GIF” формата на подблокове се налага всеки от тях да се чете поотделно и да се изпраща към “LZW” декодера. Повечето такива блокове са с максимално позволената големина от 255 байта, затова максималната големина на буфера е точно 255 байта. Тъй като процесът по кодирането не отчита край или начало на нов ред, може да се случи те да попаднат по средата на някой подблок. Форматът на декодираното изображение е максимално опростен. Всеки пиксел в декодиран ред от изображението е с големина един байт и съдържа индекс за цвят, сочещ или към глобалната, или към локалната цветова палитра. Това понякога е недостатък, тъй като изображение с 1 бит на пиксел се налага да използва 8-битови стойности за индекс на цвета и двуелементна цветова палитра.

Обикновено редовете от изображението се съхраняват последователно – започвайки от първия и завършвайки с последния, но форматът “GIF” позволява и друг тип съхранение – “interlaced”. При него всички четни редове се запазват най-напред, после следват нечетните, като при всяко следващо сканиране се обхващат все повече и повече редове от изображението. Стандартната схема на сканиране за “GIF” формата е такава, че с 4 сканирания да се предаде цялото изображение. При първото сканиране се стартира от ред 0 и се чете всеки осми ред. При второто сканиране се започва от четвърти ред и отново се чете всеки осми ред. При третото се започва от втория ред и се чете всеки четвърти, а при последното сканиране се започва от първия ред и се чете всеки втори. Така всички редове се декодират и получаваме оригиналното изображение. На следната схема се виждат разликите между режимите “interlaced” и “non-interlaced” за изображение с 16 реда:

Въвеждането на режима “interlaced” се налага най-вече заради глобалната мрежа Интернет, където скоростта на пренос на информацията не е висока и зареждането на едно по-голямо изображение би отнело време. Идеята на този режим е, че ако потребителят успее да зареди около 50% от изображението, той ще получи визуална представа за цялото изображение, макар и с няколко липсващи реда, и ще може да прецени дали да изчака цялото му зареждане, или евентуално да го прекъсне. За сравнение при “non-interlaced” режим за 50% от изображението потребителят ще има визуална представа само за горната половина на изображението, което може да не е достатъчно за преценка, дали му трябва или не, и се налага да остави пълното му зареждане.

Появява се проблем, при преобразуването на “Interlaced GIF” в друг формат. Налага се създаването на таблица, съдържаща редовете в нормалния им “non-interlaced” ред. В последствие се създава таблица за редовете на “interlaced” изображението:

WORD i, j;
WORD RowTable1[16];
WORD RowTable2[16];
WORD ImageHeight = 16;
/* брой редове в изображението */
for (i = 0; i < ImageHeight; i++) /* инициализация на таблицата за “non-interlaced” режима*/
RowTable1[i] = i;
j = 0;
for (i = 0; i < ImageHeight; i += 8, j++)
/* първо сканиране на “interlaced” изображението */
RowTable2[i] = RowTable1[j];
for (i = 4; i < ImageHeight; i += 8, j++)
/* второ сканиране на “interlaced” изображението */
RowTable2[i] = RowTable1[j];
for (i = 2; i < ImageHeight; i += 4, j++)
/* трето сканиране на “interlaced” изображението */
RowTable2[i] = RowTable1[j];
for (i = 1; i < ImageHeight; i += 2, j++)
/* четвърто сканиране на “interlaced” изображението */
RowTable2[i] = RowTable1[j];

Получават се два масива, като първият “RowTable1[ ]” е за “non-interlaced” режима, а вторият “RowTable2[ ]” е за “interlaced” режима: 

RowTable1[ ]
RowTable2[ ]
0
0
1
8
2
4
3
9
4
2
5
10
6
5
7
11
8
1
9
12
10
6
11
13
12
3
13
14
14
7
15
15

Възстановяването на “non-interlaced” изображението от “interlaced” вече става много лесно. Просто нулевият ред на “non-interlaced” изображението е нулев в “interlaced”, първият е осми, вторият – четвърти и т.н.

обратно към навигационното меню

“Trailer”

Големината му е един байт и той винаги е последен в “GIF” файла. Стойността му също е константа – “3Bh” и с нея се указва края на потока от данни.

обратно към навигационното меню

“GIF89a”

Тази версия на “GIF” формата излиза на пазара през юли 1989 г. Въпреки, че доста от нещата са същите, както в предишната му версия, има добавени няколко информационни блока, които не са дефинирани в “GIF87a”. Структурата на новата версия е следната:

Както при “GIF87a” и тук файлът започва със заглавна част, “Logical Screen Descriptor” и опционна глобална цветова палитра. Блоковете на изображението също са запазени, както и байтът за край – “Trailer”. Дотук обаче с приликите. В новата версия се въвежда така нареченият “Control Extensions”, който съдържа четири на брой разширения към оригиналната версия на “GIF”. Те представляват специализирани блокове с информация за контрол на процеса по рендериране на полезните данни в изображението. Новите блокове са “Graphics Control Extension”, “Plain Text Extension”, “Comment Extension” и “Application Extension”.

Блокът, наречен “Graphics Control Extension”, контролира как изображението или текстът се визуализират на екрана. Съдържа информация за прозрачност, евентуално дали се налага интервенция от потребителя при визуализация и др.

Блокът “Plain Text Extension” позволява в един “GIF” файл да се съхранява както “ASCII” текст, така и растерно изображение. В предишната версия това също е възможно, но там текстът се рендерира като част от изображението, докато тук той е отделно от него и само се наслагва на определената му позиция.

Блокът “Comment Extension” съдържа “ASCII” текст, който се използва за вмъкване на коментари в “GIF” потока от данни.

На последно място “Application Extension” блокът позволява съхраняване на информация, която може да се чете само от приложенията, поддържащи “GIF” формата. Това може да са примерно допълнителни инструкции за визуализацията на изображението както само по себе си, така и в комбинация с други “GIF” изображения.

Броят на тези блокове в един “GIF” файл не е ограничен, както и мястото им на появяване в структурата му, стига да са след глобалната цветова палитра, преди “Trailer” байта и не вътре в данните за изображението. Съществуват и изключения на това правило, но те ще бъдат разгледани подробно по-надолу. Всяко разширение започва с представително поле със стойност “21h”, която идентифицира блока. Следва етикет на блока, който указва информацията вътре в него, като стойността му варира от “00h” до “FFh”. Важно е да се отчете, че нито едно от описаните до сега разширения не е задължително.

обратно към навигационното меню

Блок “Graphics Control Extension”

Информацията в този блок се използва за модифициране на блока с данните на изображението, който следва веднага след него. Възможно е модифициране както на растерно изображение, така и на “ASCII” текст. Позиционирането на блока е фиксирано, като е позволен максимум един за дадено изображение във файла. Големината му е 8 байта и има следната структура:

typedef struct _GifGraphicsControlExtension {
BYTE Introducer; /* представително поле (винаги "21h ” ) */
BYTE Label; /* етикет на разширението (винаги "F9h ” ) */
BYTE BlockSize; /* големина на полетата, които следват (винаги "04h ” ) */
BYTE Packed; /* флагове и методи, свързани с визуализацията */
WORD DelayTime; /* закъснение между визуализацията на различните изображения ( стотни от секундата ) */
BYTE ColorIndex; /* индексна стойност на прозрачния цвят */
BYTE Terminator; /* указва край на разширението (винаги 0) */
} GIFGRAPHICCONTROL;

Полето “Packed” съдържа четири подполета, като бит 0 е най-младши:

бит 0

флаг за прозрачен цвят

бит 1

флаг за интервенция от потребител

битове 2-4

опции за изображението след визуализация

битове 5-7

резервирани ( винаги нули )

Ако бит 0 е единица, полето “ColorIndex” съдържа индекса на цвета, който е прозрачен, в противен случай няма такъв цвят. Ако се очаква интервенция от потребителя преди преминаването към следващото изображение, бит 1 е единица, иначе – нула. Битовете от 2 до 4 съдържат различни опции за изображението след неговата визуализация – за стойност “00h” не е дефинирано какво да се прави, за “01h” – изображението не се изтрива, за “02h” – изображението се замества с цвета за фон, и за “04h” – изображението се замества с предишното.

Ако е зададено време в полето “DelayTime” и флагът за интервенция на потребител е единица, файлът продължава със следващото изображение при изпълнение на едно от двете условия.

обратно към навигационното меню

Блок “Plain Text Extension”

Броят такива блокове в “GIF” файла е неограничен. За визуализация на текста се съставя мрежа от данни, като се задават нейните широчина, височина и позиция на екрана. Определя се и големината на всяка клетка, като само един символ се визуализира в една клетка. Цветовете на текста и на фона се вземат от глобалната цветова палитра. Големината на блока е 15 байта и има следната структура:

typedef struct _GifPlainTextExtension {
BYTE Introducer; /* представително поле (винаги "21h ” ) */
BYTE Label; /* етикет на разширението (винаги “01 h ” ) */
BYTE BlockSize; /* големина на полетата, които следват (винаги "0Ch ” ) */
WORD TextGridLeft; /* позиция на текстовата мрежа по Х ( отместване от горния ляв ъгъл на екрана ) */
WORD TextGridTop; /* позиция на текстовата мрежа по Y ( отместване от горния ляв ъгъл на екрана ) */
WORD TextGridWidth; /* широчина на текстовата мрежа в пиксели */
WORD TextGridHeight; /* височина на текстовата мрежа в пиксели */
BYTE CellWidth; /* широчина на клетка от мрежата в пиксели */
BYTE CellHeight; /* височина на клетка от мрежата в пиксели */
BYTE TextFgColorIndex; /* индексна стойност на цвета на текста */
BYTE TextBgColorIndex; /* индексна стойност на цвета на фона */
BYTE PlainTextData; /* текстът, който трябва да се рендерира */
BYTE Terminator; /* указва край на разширението (винаги 0) */
} GIFPLAINTEXT;

обратно към навигационното меню

Блок “Application Extension”

Броят на тези блокове не е ограничен, а информацията вътре в тях може да се чете само от приложенията, които поддържат “GIF” формата. Големината на блока е 14 байта със следната структура:

typedef struct _GifApplicationExtension {
BYTE Introducer; /* представително поле (винаги "21h ” ) */
BYTE Label; /* етикет на разширението (винаги “FF h ” ) */
BYTE BlockSize; /* големина на полетата “Identifier” и “AuthentCode” (винаги "0 B h ” ) */
CHAR Identifier[8]; /* идентификатор на приложението */
BYTE AuthentCode[3]; /* автентичен код на приложението */
BYTE ApplicationData; /* информацията, която се ползва от приложенията */
BYTE Terminator; /* указва край на разширението (винаги 0) */
} GIFAPPLICATION;

Полето “Identifier” може да съдържа до 8 седембитови “ASCII” символи. Те се използват, за да идентифицират приложението, което е създало този блок. Ако стойността на това поле се разпознае, следва четене на блока и изпълнение на инструкциите вътре, ако ли не, то блокът отново се чете, но не се предприемат действия.

Полето “AuthentCode” се използва за уникално идентифициране на софтуерното приложение, създало блока. То може да съдържа сериен номер, версия или уникален бинарен код на приложението. Една от възможните функции на това поле е да ограничи достъпа до “GIF” файла само на определени версии на приложението, което го е създало.

обратно към навигационното меню

Блок “Comment Extension”

Броят “Comment Extension” блокове не е ограничен в един “GIF” файл. Информацията в тях е предназначена единствено за потребителите и се пренебрегва от приложенията. Обикновено коментарът съдържа източник на изображението, автор, софтуерното приложение, с което е създадено, време и дата на създаване, права на ползване и т.н. Блокът варира от 5 до 259 байта и има следната структура:

typedef struct _GifCommentExtension {
BYTE Introducer; /* представително поле (винаги "21h ” ) */
BYTE Label; /* етикет на разширението (винаги “FEh ” ) */
BYTE CommentData; /* съдържа един или повече подблокове от “ASCII” текст */
BYTE Terminator; /* указва край на разширението (винаги 0) */
} GIFCOMMENT;

обратно към навигационното меню

"Joint Photographic Experts Group (JPEG)"

тип на изображението

растерно

брой битове на пиксел

до 24 бита

компресия

“JPEG”

максимален размер на изображението

64Kx64K

създател

“C-Cube Microsystems”

поддържани платформи

“Windows”, “Macintosh”, “MS-DOS”, “UNIX”

Форматът всъщност се нарича “JPEG File Interchange Format (JFIF)” и е разработен от “C-Cube Microsystems” с цел да се пренасят изображения между по принцип несъвместими приложения и платформи. “JFIF” файлът е всъщност поток от кодирани “JPEG” данни с няколко ограничения и идентификационен маркер.

обратно към навигационното меню

Файлова структура

Както “JPEG”, така и “JFIF” са байтови потоци, които винаги съхраняват 16-битови думи. Данните в “JPEG” са структурирани на потоци от блокове, като всеки от тях се идентифицира с определена стойност на маркер. Първите два байта на всеки “JPEG” поток указват начало на изображението – “Start Of Image ( SOI)” и имат съответно стойности “FFh” и “D8h”. При “JFIF” файла веднага след "SOI” идва маркер за приложението “JFIF APP0”, който се състои от кода на маркера – “FFh E0h” и символите “JFIF”. Отделно е възможно да има един или повече “JFIF” разширяващи маркери, след които идват полезните данни.

Форматът “JFIF” няма обособена отделна заглавна част, тя се формира от маркерите "SOI” и “JFIF APP0”, които образуват следната структура:

typedef struct _JFIFHeader {
BYTE SOI[2]; /* 00h маркер за начало на изображението (“FFh D8h”) */
BYTE APP0[2]; /* 02h маркер на приложението (“FFh E0h”) */
BYTE Length[2]; /* 04h големина на полето “APP0” и “Lenght” */
BYTE Identifier[5]; /* 06h код за идентификация на “JFIF” поток от данни (“4Ah 46h 49h 46h 00h (JFIF)” */
BYTE Version[2]; /* 07h версия на “JFIF” спецификацията ( за 1.02 – “01h 02h”) */
BYTE Units; /* 09h мерни единици, използвани за разделителната способност (“01h” – пиксели на инч; “02h” – пиксели на сантиметър; “00h” – не е дефинирано, ползва се коефициент на формата ) */
BYTE Xdensity[2]; /* 0Ah разделителна способност по хоризонтала */
BYTE Ydensity[2]; /* 0Ch разделителна способност по вертикала */
BYTE XThumbnail; /* 0Eh брой пиксели по Х за иконката */
BYTE YThumbnail; /* 0Fh брой пиксели по Y за иконката */
} JFIFHEAD;

Иконката е записана в маркера “JFIF APP0” и представлява умалено копие на оригиналното изображение във файла, като не подлежи на компресия. В по-новите версии на спецификацията “JFIF” се дефинират разширения, съдържащи маркери, които позволяват иконката да се съхранява отделно от идентификационния маркер. При всички положения размерът на това изображение не трябва да надхвърля 64 К Byte. Структурата на споменатите разширения има следния вид:

typedef struct _JFIFExtension {
BYTE APP0[2]; /* 00h маркер на приложението (“FFh E0h”) */
BYTE Length[2]; /* 02h големина на разширението в байтове */
BYTE Identifier[5]; /* 04h код за идентификация на “JFXX” разширение (“4Ah 46h 58 h 58 h 00h (JFXX)” */
BYTE ExtensionCode; /* 09h код на разширението – указва типа информация, която съдържа разширението */
} JFIFEXTENSION;

След този маркер следва полезната информация в него, която варира по големина и тип в зависимост от кода на разширението. “JFIF” декодерите трябва да имат възможност за прескачане на сегменти, чийто код на разширение не разпознават. Наличието на “JFIF” маркер гарантира, че файлът е изпълнен по “JFIF” спецификацията. Препоръчва се полезните данни да са кодирани, ползвайки основния “JPEG” алгоритъм, за да се осигури максимална съвместимост. Идентифицирането на “JFIF” файл става много лесно – достатъчно е да се сканира за последователните стойности “FFh D8h FFh”, което представлява "SOI” маркерът, последван от друг маркер. Ако се следва “JFIF” спецификацията, следващата стойност би трябвало да е “E0h”, за да се получи “JFIF APP0” маркера, но е възможно и записването на други маркери между "SOI” и “JFIF APP0”. При откриване на поредицата "4Ah 46h 49h 46h 00h (JFIF)” се маркира начало на “JFIF” потока от данни. Ако обаче след “FFh D8h FFh” няма други дефинирани стойности, това означава, че файлът съдържа неструктуриран “JPEG” поток от данни. Всички “JFIF” и “JPEG” потоци завършват с маркер за край на изображението “End Of Image (EOI)”, който има стойност “FFh D9h”.

обратно към навигационното меню

"Portable Network Graphic Format (PNG)"

тип на изображението

растерно

брой битове на пиксел

от 1 до 48 бита

компресия

“LZ77”

максимален размер на изображението

2Gx2G

създател

Thomas Boutell, Tom Lane

поддържани платформи

“Windows”, “Macintosh”, “MS-DOS”, “UNIX”

Този формат има възможност за съхраняване на изображения до 16 бита на пиксел за сивата гама, до 48 бита на пиксел за реални цветове и до 16 бита на пиксел за прозрачност. Поддържа прогресивна визуализация на изображението, съхранява информация за гамата, прозрачността и текстурата му, както и използва много ефикасен беззагубен метод за компресия. "PNG” форматът е реализиран с идеята да замести “GIF”, като добави нововъведенията, описани по-горе. Накратко ще изложим някои прилики, разлики и подобрения, свързани с двата формата.

Прилики:

    • форматите са организирани като поток от данни;
    • използват беззагубна компресия;
    • поддържат се изображения, които използват индексни цветове;
    • прогресивна визуализация на изображението;
    • поддържат прозрачност;
    • възможност за съхранение на публично достъпна и лична информация;
    • независими от хардуера и операционната система.

Подобрения в "PNG” спрямо “GIF”:

    • методът за компресия се разпространява безплатно;
    • по-бърза схема за “interlaced” прогресивна визуализация;
    • по-подробно представяне на личната информация.

Нововъведения в "PNG”:

    • възможност за съхраняване на пълноцветни изображения до 48 бита на пиксел;
    • възможност за съхраняване на изображения в сивата гама до 16 бита на пиксел;
    • 16-битов канал за прозрачност;
    • гама индикатор;
    • "CRC” метод за откриване на грешка в потока от данни;
    • стандартизиран диалогов прозорец за внедряване в приложения, които поддържат "PNG”;
    • стандартизирани изображения за тестване на приложения, които четат "PNG”.

Опции, които се поддържат от “GIF”, но не и от "PNG”:

    • възможност за съхраняване на няколко изображения в един файл;
    • възможност за създаване на анимация между отделните изображения във файла;
    • заплащането на лиценз за ползването на кодери и декодери за “GIF” формата.

Форматът "PNG” е така проектиран, че добавянето на нови възможности става много лесно, без да се нарушава функционалността му или пък да се налагат промени в софтуера, който вече е на пазара.

обратно към навигационното меню

Файлова структура

Файловият формат "PNG” се състои от 8-байтов идентификационен подпис, след който има три или повече парчета с данни. Парчетата са всъщност независими един от друг блокове, съдържащи специфични данни за дадена структура. Всеки блок има своя собствена идентификация в зависимост от вътрешния си формат. Четенето става на блокове, започвайки от началото и свършвайки в края на файла.

Дефинирани са 4 стандартни парчета в "PNG” формата, които задължително се поддържат от всеки "PNG” кодер и декодер. Те са както следва:

    • заглавно парче (“IHDR”) – съдържа основна информация за изображението и задължително трябва да е първо след идентификационния подпис. Допуска се само едно такова парче в един "PNG” файл.
    • парче за палитрата (“PLTE”) – съдържа цветовата палитра на изображението. Съществува само ако изображението използва цветова палитра и задължително е преди парчето с полезната информация.
    • парче с полезна информация (“IDAT”) – съдържа полезните данни от изображението. Позволяват се няколко парчета в един файл, но трябва да се подредени последователно.
    • парче за край на файла (“IEND”) – задължително е последно във файла, като маркира неговия край.

От тези четири парчета само “PLTE” не е задължително, останалите присъстват във всеки "PNG” файл. Така изглежда структурата на един такъв файл съответно със и с парче за палитра:

идентификационен подпис

IHDR

PLTE

IDAT

IEND


идентификационен подпис

IHDR

IDAT

IEND

Съществуват парчета, които са допълнителни и не са задължителни. Наричат се “ancillary chunks” и ако декодерът не ги поддържа, изображението, което ги ползва, може да не се рендерира правилно. Затова се препоръчва най-често срещаните допълнителни парчета да бъдат поддържани от декодерите. Допълнителните и задължителните парчета се наричат стандартни, а има и такива със специално предназначение. Всички парчета, които присъстват в спецификацията на "PNG” формата, са описани в таблицата, като са подредени според евентуалното им появяване във файла:

име на парчето

възможност за многократно появяване в един файл

може и да го няма

позиция във файла

IHDR

не

не

винаги е първото парче

cHRM

не

да

преди PLTE и IDAT

gAMA

не

да

преди PLTE и IDAT

sBIT

не

да

преди PLTE и IDAT

PLTE

не

да

преди IDAT

bKGD

не

да

след PLTE и преди IDAT

hIST

не

да

след PLTE и преди IDAT

tRNS

не

да

след PLTE и преди IDAT

oFFs

не

да

преди IDAT

pHYs

не

да

преди IDAT

sCAL

не

да

преди IDAT

IDAT

да

не

последователно след другите IDAT

tIME

не

да

където и да е

tEXt

да

да

където и да е

zTXt

да

да

където и да е

fRAc

да

да

където и да е

gIFg

да

да

където и да е

gIFt

да

да

където и да е

gIFx

да

да

където и да е

IEND

не

не

винаги последно парче

Идентификационният подпис в "PNG” формата съдържа информация, която се ползва за да се верифицира, че файлът и данните вътре наистина отговарят на "PNG” спецификацията. Големината му е 8 байта и има следната структура:

typedef struct _PngSignature {
BYTE Signature[8]; /* идентификатор (винаги "89 h 50 h 4E h 47 h 0D h 0A h 1A h 0Ah ” ("‰PNG\r\n \n") ) */
} PNGSIGNATURE;

Тази на пръв поглед безмислена поредица от символи има своето предназначение. Първата стойност – "89 h” се използва, за да се идентифицира файлът като бинарен. Ако ги нямаше тези 8 бита, първата стойност от поредицата щеше да е “09h” и щеше да носи информация относно това как файлът се е повредил. Останалите байтове имат следните функции:

  • “PNG” – визуална идентификация на потока;
  • "\r\n; \r; \n; \n\r” – открива трансфери на файлове, които обръщат последователността за нов ред;
  • "” – спира "PNG” потока при “MS-DOS” операционна система;
  • "\n” – открива проблеми при трансфер на файла с преминаване “CR/LF”.

След идентификационния подпис следват 3 или повече парчета, които имат един и същ базисен формат, но съдържат различни по размер данни:

typedef struct _PngChunk {
DWORD DataLength; /* брой байтове записани в полето “Data[ ]” */
DWORD Type; /* идентификационен код на типа парче (4 байта ) */
BYTE Data[ ]; /* полезната информация в парчето ( може да е нула ) */
DWORD Crc; /* "CRC -32 ” стойност за проверка за грешки в полетата “Data[ ]” и “Type” */
} PNGCHUNK;

Всеки байт на полето “Type” може да е или голяма, или малка буква от “ASCII” кода. По тази причина при декодиране това поле се третира като буквен код, а не числов стринг.

Минималният размер на парчетата е 12 байта и се постига, когато не съдържа полезна информация, иначе може да достигне максимум 2 гигабайта.

обратно към навигационното меню

Задължителни парчета

Заглавно парче – “IHDR”

Съдържа информация за изображението в "PNG” файла. Винаги е на първо място в структурата му и има големина 13 байта:

typedef struct _IHDRChunk {
DWORD Width; /* широчина на изображението в пиксели */
DWORD Height; /* височина на изображението в пиксели */
BYTE BitDepth; /* брой битове на пиксел */
BYTE ColorType; /* интерпретатор на цвета (0 – гама на сивото, 2 – пълноцветно, 3 – индексен цвят, 4 – гама на сивото с прозрачност, 6 – пълноцветно с прозрачност ) */
BYTE Compression; /* индикатор за компресията ( винаги 0 – метод на свиване ) */
BYTE Filter; /* индикатор за филтриране преди компресията ( винаги 0 – адаптивен филтър ) */
BYTE Interlace; /* тип на ползваната “interlaced” схема (0 – “non-interlaced”, 1 – “Adam7 interlaced”) */
} IHDRCHUNK;

обратно към навигационното меню

Парче за палитрата – “PLTE”

Присъства във всички "PNG” изображения, които ползват индексен цвят, тоест когато стойността на полето “ColorType” е 3. Пълноцветните "PNG” изображения също може да имат палитра. Тя се използва от приложенията, които не могат да работят с толкова много цветове, за да квантува данните на изображението. Само една палитра е позволена в даден "PNG” файл. Големината й е от 3 до 768 байта и има следната структура:

typedef struct _PLTEChunkEntry {
BYTE Red; /* червен компонент (0 = черно, 255 = маскимум) */
BYTE Green; /* зелен компонент (0 = черно, 255 = максимум) */
BYTE Blue; /* син компонент (0 = черно, 255 = максимум) */
} PLTECHUNKENTRY;
PLTECHUNKENTRY PLTEChunk[ ]; /* масив с максимум 256 елемента, всеки от които има по три полета със стойности – съответно за червен, зелен и син цвят. */

обратно към навигационното меню

Парче с полезна информация – “IDAT”

Съхранява самото изображение, като то винаги е компресирано според "PNG” спецификацията. Възможно е информацията да се раздели в няколко последователни “IDAT” парчета за по-лесно буфериране. Големината им варира от 0 до 2 гигабайта.

обратно към навигационното меню

Парче за край на файла – “IEND”

Това винаги е последното парче във всеки "PNG” файл – “IEND”. То не съдържа каквато и да било допълнителна информация.

обратно към навигационното меню

Допълнителни парчета

Форматът "PNG” дефинира 10 допълнителни парчета, които може да се появят в потока. Някои от тях са свързани с характеристики на самото изображение и са важни за неговата правилна визуализация.

обратно към навигационното меню

Парче за цвят на фона – “bKGD”

В него се задава цвят на фона, въпреки че то може да бъде игнорирано от декодера и да бъде зададен произволен цвят за фон. Форматът му зависи от изображението, и по-точно от полето “ColorType” в заглавната част на файла. Ако изображението е с индексен цвят, това парче е с големина само един байт, съдържащ индекса от палитрата за цвета на фона:

typedef struct _bKGDChunkEntry {
BYTE Index; /* индекс от палитрата за цвета на фона */
} BKGDCHUNKENTRY;

За изображения в гамата на сивото, със или без прозрачност, се използва двубайтово парче за точно задаване нивото на сивото:

typedef struct _bKGDChunkEntry {
WORD Value; /* стойност от сивата гама за фон на изображението */
} BKGDCHUNKENTRY;

Ако пък изображението е пълноцветно, със или без прозрачност, парчето съдържа 3 двубайтови стойности, задаващи съответно червения, зеления и синия компонент на фона:

typedef struct _bKGDChunkEntry {
WORD Red; /* стойност на червения компонент на фона */
WORD Green; /* стойност на зеления компонент на фона */
WORD Blue; /* стойност на синия компонент на фона */
} BKGDCHUNKENTRY;

обратно към навигационното меню

Парче за цветовете и бялата точка – “cHRM”

То съдържа информация за "RGB” стойностите, базирани на “CIE XYZ” цветовото пространство. Взети са стойностите само по “x” и “y” и са умножени по 100 000:

typedef struct _cHRMChunkEntry {
DWORD WhitePointX; /* стойност по Х за бялата точка */
DWORD WhitePointY; /* стойност по Y за бялата точка */
DWORD RedX; /* стойност по Х за червеното */
DWORD RedY; /* стойност по Y за червеното */
DWORD GreenX; /* стойност по Х за зеленото */
DWORD GreenY; /* стойност по Y за зеленото */
DWORD BlueX; /* стойност по Х за синьото */
DWORD BlueY; /* стойност по Y за синьото */
} CHRMCHUNKENTRY;

обратно към навигационното меню

Парче за гамата на изображението – “gAMA”

В него се съдържа оригиналната гама стойност на изображението, умножена по 100 000. Това парче не е задължително, но при наличието му силно се препоръчва правилното му декодиране:

typedef struct _gAMAChunkEntry {
DWORD Gamma; /* стойност на гамата */
} GAMACHUNKENTRY;

обратно към навигационното меню

Парче за хистограмата на изображението – “hIST”

Съдържа средната честота на появяване на различните цветове в изображението. Структурата му е масив от двубайтови елементи, като за всеки елемент от палитрата е отреден по един:

typedef struct _hISTChunkEntry {
WORD Histogram[ ]; /* данни за хистограмата */
} HISTCHUNKENTRY;

обратно към навигационното меню

Парче за размерите на пикселите – “pHYs”

Специфицира разделителната способност на изображението:

typedef struct _pHYsChunkEntry {
DWORD PixelsPerUnitX; /* пиксели на единица по оста Х */
DWORD PixelsPerUnitY; /* пиксели на единица по оста Y */
BYTE UnitSpecifier; /* тип на мерната единицата ( 0 = неопределена, 1 = метър ) */
} PHYSCHUNKENTRY;

обратно към навигационното меню

Парче за старшите битове – “sBIT”

Указва битовете на пиксел за оригиналното изображение. Ако "PNG” кодерът се опита да запише изображение, чийто брой битове на пиксел не се поддържат от формата, се налага да бъде повишен броят им до най-близкото допустимо ниво. Например, за да се съхранят "RGB” данни във формат "RGB555”, първо ще се скалират до "RGB888”, а парчето за старшите битове ще запише броя битове на пиксел за оригиналното изображение. Парчето има четири възможни формата, кой ще се използва зависи от типа изображение, указано с полето “ColorType” в заглавното парче:

/* изображение в гамата на сивото (“ColorType=0”) */

typedef struct _sBITChunkEntry {
BYTE GrayscaleBits; /* старши битове за гамата на сивото */
} SBITCHUNKENTRY;  

/* Пълноцветно или изображение с индексен цвят ( "ColorType = 2 ” или "ColorType = 3 ” ) */

typedef struct _sBITChunkEntry {
BYTE RedBits; /* старши битове за червеното */
BYTE GreenBits; /* старши битове за зеленото */
BYTE BlueBits; /* старши битове за синьото */
} SBITCHUNKENTRY;  

/* изображение в гамата на сивото с прозрачност ( "ColorType = 4 ” ) */

typedef struct _sBITChunkEntry {
BYTE GrayscaleBits; /* старши битове за гамата на сивото */
BYTE AlphaBits; /* старши битове за прозрачност */
} SBITCHUNKENTRY;  

/* пълноцветно изображение с прозрачност ( "ColorType = 6 ” ) */

typedef struct _sBITChunkEntry {
BYTE RedBits; /* старши битове за червеното */
BYTE GreenBits; /* старши битове за зеленото */
BYTE BlueBits; /* старши битове за синьото */
BYTE AlphaBits; /* старши битове за прозрачност */
} SBITCHUNKENTRY;

обратно към навигационното меню

Парче за текста – “tEXt”

Обикновено съдържа информация, която се чете с просто човешко око, като например името на автора на изображението, права за разпространение и др. Структурата е следната:

typedef struct _tEXtChunkEntry {
char Keyword[ ]; /* тип на информацията записана в полето “Text[ ]” ( големина от 1 до 79 байта ) */
BYTE NullSeparator; /* разделител между полетата “Keyword[ ]” и “Text[ ]” ( винаги 0 ) */
char Text[ ]; /* полезна текстова информация ( големината му зависи от полето “DataLength” в заглавното парче ) */
} TEXTCHUNKENTRY;

Стойността на полето “Keyword[ ]” указва интелектуално съдържание, свързано с текста, записан в полето “Text[ ]”. Дефинираните ключове думи в стандарта "PNG” са:

Title

Author

Description

Copyright

Creation Time

Software

Disclaimer

Warning

Source

Comment


Допълнителни ключови думи може да се дефинират чрез публичната им регистрация или да бъдат въведени само от и за определени приложения.

обратно към навигационното меню

Парче за времето на последната промяна в изображението – “tIME”

Съдържа времето когато е регистрирана последната промяна на изображението. Структурата на това парче е:

typedef struct tIMEChunkEntry {
WORD Year; /* година */
BYTE Month; /* месец */
BYTE Day; /* ден */
BYTE Hour; /* час */
BYTE Minute; /* минути */
BYTE Second; /* секунди */
} TIMECHUNKENTRY;

обратно към навигационното меню

Парче за прозрачност – “tRNS”

Съдържа стойността на цвета, който е прозрачен, за изображение без канал за прозрачност. Всички пиксели с тази стойност са прозрачни при пълноцветни изображения или такива в гамата на сивото. За изображения с индексен цвят се записва масив от стойности за прозрачността – максимум по един за всеки елемент от палитрата. Всички елементи, които нямат зададена стойност за прозрачност, се смятат изцяло видими. Съществуват 3 различни формата за това парче, в зависимост от полето “ColorType”:

/* изображение в гамата на сивото (“ColorType=0”) */

typedef struct _tRNSChunkEntry {
WORD TransparencyValue; /* стойност на прозрачния цвят */
} TRNSCHUNKENTRY;  

/* пълноцветно изображение ( "ColorType = 2 ” ) */

typedef struct _tRNSChunkEntry {
WORD RedTransValue; /* стойност на червения компонент от прозрачния цвят */
WORD GreenTransValue; /* стойност на зеления компонент от прозрачния цвят */
WORD BlueTransValue; /* стойност на синия компонент от прозрачния цвят */
} TRNSCHUNKENTRY;  

/* изображение с индексен цвят ( "ColorType = 3 ” ) */

typedef struct _tRNSChunkEntry {
BYTE TransparencyValues[ ]; /* стойности на прозрачните цветове */
} TRNSCHUNKENTRY;

обратно към навигационното меню

Парче за компресираната текстова информация

Съхранява голям обем от текстова информация в компресиран вид. Има същата структура като парчето за текста, но с тази разлика, че полето “Text[ ]” съдържа информация, компресирана по метода, използван обикновено за данните от изображението.

обратно към навигационното меню

Полезни данни

Полезната информация в изображението е подредена на редове от ляво на дясно и от горе на долу. Пикселите са част от тези редове, като не се ползват такива за допълване до цял байт. Тези от тях с големина по-малка от 8 бита се пакетират в байтове, като първият бит е най-старшият. Самите редове от изображението пък винаги започват от цял байт и трябва да завършат на такъв, което може да означава, че се налага допълване. В тях има и така нареченият байт филтър, който се използва при компресията и декомпресията и указва типа на филтриращия алгоритъм. Дори да няма филтриране, байтът все пак присъства в реда и не се смята за полезна информация.

Изображения до 8 бита на пиксел може да присвоят стойностите на цветовете си на палитра или директно да ги запишат в изображението като стойности от гамата на сивото. Пълноцветните пиксели винаги използват трикомпонентно представяне, като може да се появи и четвърти за прозрачност. Изображенията в гамата на сивото и тези с индексен цвят имат по един семпъл на пиксел, който за дадено изображение е винаги с еднаква големина. Тази големина се характеризира от битове в него, като може да варира от 1 до 16. За изображение с индексен цвят се указва максималният брой цветове в палитрата. Съществуват и изображения с повече от един семпъл на пиксел, като всички семпли в един пиксел трябва да са еднакво големи – 8 или 16 бита, а самите пиксели може да са от 16 до 64 бита.

обратно към навигационното меню

Канал за прозрачност

Пълноцветни изображения и тези в гамата на сивото, съдържащи от 8 до 16 бита на пиксел, могат да имат информация за прозрачност, наречена “alpha mask”. Ако тази маска съществува, то към всеки пиксел се добавя семпъл със стойността на прозрачността. Изображенията с индексен цвят може да използват парчето за прозрачност за съхраняването на тези стойности. Минималната стойност на прозрачността е нула, което означава напълно невидим пиксел, а максималната – 255, указва, че пикселът е напълно видим. Същото се смята и когато не се използва маска за прозрачност.

обратно към навигационното меню

“Interlacing”

Обикновенно "PNG” изображенията се запазват като серии от редове, започвайки от първия най-отгоре и завършвайки с последния най-отдолу. Стандартът "PNG” поддържа и по-различен начин за визуализация на изображението, като прогресивно го изгражда от ниска разделителна способност до пълна такава. Типична схема за “interlacing” е тази, която се ползва при “GIF” формата. В "PNG” се използва обаче друга доста ефективна схема, наречена “Adam7”. Тя предава изображението на 7 части, като първите 6 сканирания предават четните редове – 0, 2, 4 и т.н., а последното сканиране предава всички нечетни. Вместо да съдържат всички пиксели от четните редове, първите 6 сканирания предават само точно определени пиксели от тях. Първото и второто сканиране съдържат всеки 64-ти пиксел на изображението. Третото сканиране всеки 32-ри, четвъртото – всеки 16-ти, петото – всеки 8-ми и шестото всеки 4-ти. Последното седмо сканиране предава всички останали нечетни редове, тоест половината изображение. Този тип “interlacing” позволява много по-бърза визуализация на изображението, отколкото ако се предаваха цели редове. Освен това само след зареждане на 20-30 % от изображението вече се добива представа за съдържанието му, докато при “GIF” бяха нужни поне 50%. Недостатък при ползване на “interlace” схема е, че се получава по-голям изходен файл, понеже се намалява ефективността на компресията, тъй като разликата между два отдалечени един от друг пиксели е много по-голяма, отколкото между два съседни. Обикновено се получава 10% по-голям файл, което в някои случаи е допустимо. Принципът на действие на алгоритъма за “interlacing” “Adam7” е следният, като се има предвид, че всяка клетка представлява байт от ред на изображението, а числата в тях – на кое сканиране се предават:

1

6

4

6

2

6

4

6

7

7

7

7

7

7

7

7

5

6

5

6

5

6

5

6

7

7

7

7

7

7

7

7

3

6

4

6

3

6

4

6

7

7

7

7

7

7

7

7

5

6

5

6

5

6

5

6

7

7

7

7

7

7

7

7

обратно към навигационното меню

Компресия на данните

Полезната информация на изображение в "PNG” формат винаги е в компресиран вид. Използва се разликово предсказване на стойността на пикселите плюс вариация на метода за компресия “Deflate”. Той е бил въведен от “Phil Katz” за ползване при “pkzip” архиватора. Това е беззагубен, бърз метод за компресия с добре описана документация и най-важното – поддържа се от много операционни платформи. Вариация е на “LZ77” алгоритъма, като ползва различни по големина сканиращи прозорци и сортирани хеш таблици за идентифициране на пиксели и компресирането им чрез Хъфман кодиране. Разликата в "PNG” е, че не се ползват сортираните хеш таблици и оттам отпада и нуждата от лицензиране на алгоритъма, тоест той е безплатен за вграждане и разпространение. Данните могат да бъдат филтрирани преди компресия, като така се постига нормиране на байтовите стойности и съответно по-ефективно компресиране. Филтрират се байтове в ред, а не самите пиксели, като при наличие на байтове за прозрачност те също се филтрират. Всеки ред от изображението може да използва както различен алгоритъм за филтриране, зададен му в байта филтър, така и да не ползва такъв. Ако се прилага, филтрирането е на два етапа – първият преди компресия е вторият след декомпресия. Четири от най-често използваните филтри са:

  • “Sub” филтър – съдържа разликата между байтовата стойност на текущия и предишния пиксел. Този метод позволява едни и същи семпли в пиксели с повече от един семпъл винаги да бъдат предсказвани;
  • “Up” филтър – съдържа разликата между байта на текущия пиксел и този над него от предишния ред:
  • “Average” филтър – съдържа разликата между байта на текущия пиксел и средноаритметичната стойност от горно и ляво стоящите байтове спрямо него;
  • “Path” филтър – използва линейна функция за изчисляване на стойнст. Най-близката байтова стойност от байтовете отляво, отгоре и по диагонал вляво се ползва за предсказване на текущия байт.

обратно към навигационното меню

"Tag Image File Format (TIFF)"

тип на изображението

растерно

брой битове на пиксел

от 1 до 24 бита

компресия

некомпресирано, “RLE”, “LZW”, “CCITT”, “JPEG”

максимален размер на изображението

4Gx4G

създател

“Aldus”

поддържани платформи

“Windows”, “Macintosh”, “MS-DOS”, “UNIX”

Това е най-универсалният и същевременно с най-много възможости растерен формат за неподвижни изображения, който съществува до момента. Само това, че има възможност за допълнително разширяване, и поддръжката на многобройните схеми на компресия го правят един от предпочитаните за разработчиците на приложен софтуер. Историята на “TIFF” формата датира от 1986 г., когато компанията “Aldus Corp.” го въвежда като стандартизиран метод за съхранение на черно-бели изображения, получени от скенери и софтуерни приложения за предпечатна подготовка. Извадената от фирмата публична версия на формата всъщност била негова трета преработка и затова версията му е “TIFF Revision 3.0”. Първата по-широко използвана версия на този формат e “TIFF Revision 4.0”, която била извадена в публичното пространство през април 1987 г. В нея се добавя поддръжка за некомпресирани "RGB” изображения. Следващата версия не закъснява и през август 1988 г. излиза “TIFF Revision 5.0”, като в нововъведенията са добавена възможност за съхраняване на цветни изображения с палитра и поддръжка на “LZW” алгоритъма за компресия. Последната и най-нова версия “TIFF Revision 6.0” излиза през юни 1992 г. и добавя поддръжка за “CMYK” и “YCrCb” цветови пространсва, както и за “JPEG” метода за компресия.

обратно към навигационното меню

Файлова структура

Файловете от този формат са разделени на три части – заглавна част на файла (“IFH”), файлова директория на изображението (“IFD”) и част с полезните данни от изображението. От тези три първите две са задължителни, но файлове, които съдържат само тях са изключителна рядкост. “TIFF” форматът е известен с това, че има много сложна структура, защото начините за откриването на всяка “IFD” и съответно на данните, към които тя сочи, са доста на брой. Единствената част с фиксирано местоположение във файла е “IFH”, като големината й е 8 байта и винаги е на първо място в структурата. Останалата информация се локализира посредством тази, записана в заглавната част. Файловите директории и прикрепените към тях полезни данни се наричат “TIFF subfile”, като няма ограничение в броя им в един файл. Всяка файлова директория съдържа една или повече структури, наречени етикети. Всеки етикет представлява 12-байтов запис и съдържа специфична информация за съответстващата му полезна информация от изображението. Спецификацията на “TIFF” формата дефинира повече от 70 етикета, като те задължително се намират във файловата директория и са подредени един след друг. Етикетите, които са дефинирани по спецификацията, се наричат публични и не могат да бъдат модифицирани напълно. Могат да се променят само някои техни предварително указани параметри. Съществуват обаче и лични етикети, които се използват главно от софтуерните разработчици. Те могат да бъдат модифицирани, така че да вършат съответната работа, за която са предназначени. Във версия “TIFF 6.0” терминът етикет се заменя с поле, като той се отнася за цялия 12-байтов запис, а старият термин – етикет, се отнася само за идентификационния номер на полето. Тъй като обаче много програмисти са свикнали със старите термини, то и в тази документация те ще бъдат ползвани, както са били преди въведената промяна в “TIFF 6.0”. На следната графика са дадени три възможни подреждания на структурата на “TIFF” файл, съдържащ 3 изображения:

Както се вижда, и в трите първата част винаги е заглавната. При първия метод на подреждане на останалите части се постига бързо и ефикасно четене на файловата директория. Вторият пък е най-често срещаният формат за подреждане, когато имаме няколко изображения във файла. Последният метод се използва, когато самите изображения са готови за запис преди файловите им директории. Всъщност всяка от тези директории представлява карта на това къде може да се открият дадени полезни данни от изображението в един “TIFF” файл. След откриването им може да се четат директно от “IFD” структурата или да се извлекат от позиция, на която са отместени от началото на файла. Стойността на това отместване е записана именно във файловата директория. Всички блокове в този файлов формат са свързани помежду си с такива отмествания, а не с фиксирани позиции, което означава, че софтуерът, който чете и записва “TIFF” файлове, е много сложен. Стойностите на отместванията винаги се третират като брой байтове от началото на “TIFF” файла и могат да бъдат открити на 3 характерни места в него. Първото отместване е в последните четири байта на заглавната част и указва къде се намира частта с първата файлова директория. Последните четири байта на всяка файлова директория пък указват отместването до следващата такава. Третото място, където може да се търсят стойности на отместване, е в последните 4 байта на етикетите, указващи къде се намират данните, които етикетът описва. По-голяма яснота се добива от следната графика, изобразяваща локалната организация в един “TIFF” файл:

обратно към навигационното меню

Заглавна част – “IFH”

Независимо че “TIFF” форматът е известен като един от най-сложните, той има възможно най-простата по структура заглавна част от всички разгледани файлови формати за неподвижни изображения. Съдържа 3 полета с обща големина от 8 байта:

typedef struct _TiffHeader {
WORD Identifier; /* идентификатор за вътрешното подреждане на битовете в един байт */
WORD Version; /* идентификационен номер (винаги "2Ah ” ) */
DWORD IFDOffset; /* отместване до първата файлова директория */
} TIFHEAD;

Полето “Identifier” съдържа стойността “4949h” за формата на “Intel” или “4D4Dh” за формата на “Motorola”. Всички данни след тези два байта се подчиняват на зададеното подреждане. Един от най-бързите начини за идентификация на “TIFF” файл, е да се прочетат първите 4 байта от него. Ако те са: “49h 49h 2Ah 00h” или “4Dh 4Dh 00h 2Ah”, със сигурност се работи с “TIFF”. Полето “IFDOffset” е 32-битова стойност, указваща отместването до първата файлова директория. Ако тя следва непосредствено след заглавната част, стойността на това поле е “08h”.

обратно към навигационното меню

Файлова директория – “IFD”

По структура прилича на заглавната част, като съдържа описание на полезните данни, към които е прикрепена. Съхранява височината, ширината, броя битове на пиксел, броя цветови равнини и типа на компресията за съответното изображение. Файловата директория не е фиксирана и може да варира както по големина, така и по позиция във файла. В един “TIFF” файл може да има неограничен брой файлови директории. Често те се бъркат със заглавната част, но това е далеч от истината, по-скоро се явяват нейно разширение. Изображенията в един “TIFF” файл също може да варират от нула нагоре, като всяко от тях може да има само по една файлова директория, а двете заедно образуват подфайл, който съвсем успешно може да се запише и като отделен “TIFF” файл. Вариращата големина на файловата директория се обуславя от това, че може да съдържа различен брой етикети, всеки от които носи уникална информация. Позволеният брой етикети в една файлова директория е 65 535. Форматът на “IFD” е следният:

typedef struct _TifIfd {
WORD NumDirEntries; /* брой етикети във файловата директория */
TIFTAG TagList[ ]; /* масив от етикети */
DWORD NextIFDOffset; /* отместване до следващата файлова директория ( ако няма такава, стойността му е “00h”) */
} TIFIFD;

обратно към навигационното меню

Етикети – “Tags”

Етикетът може да се смята като поле на заглавна част, но с много по-големи възможности. Той може да съдържа или да сочи към неограничени по големина данни, а също така позицията му в “IFD” не е фиксирана. 12-байтовата му структура има следния вид:

typedef struct _TifTag {
WORD TagId; /* идентификатор на етикета */
WORD DataType; /* тип на полезните данни */
DWORD DataCount; /* брой парчета от горепосочения тип */
DWORD DataOffset; /* отместване до началото на данните */
} TIFTAG;

Етикетите се записват във файловата директория в зависимост от идентификатора си. Тези с по-малки стойности на идентификатора се записват първи, а тези с най-големи са последни. Поддържаните типове за полето “DataType” са:

1

BYTE

8-битово цяло число без знак

2

ASCII

8-битов нулево терминиран стринг

3

SHORT

16 -битово цяло число без знак

4

LONG

32 -битово цяло число без знак

5

RATIONAL

две 32-битови числа без знак – използва се за дробни числа, като първите 32 бита съхраняват числителя, а вторите 32 – знаменателя

6

SBYTE

8-битово цяло число със знак

7

UNDEFINE

8-битов байт – съдържа данни, които не спадат към нито един от дефинираните типове; предимно се ползва в личните етикети

8

SSHORT

16 -битово цяло число със знак

9

SLONG

32 -битово цяло число със знак

10

SRATIONAL

две 32-битови числа със знак

11

FLOAT

4-байтова стойност, с единична точност по “IEEE” стандарт, с плаваща запетая

12

DOUBLE

8-байтова стойност, с двойна точност по “IEEE” стандарт, с плаваща запетая

Стойността на полето “DataCount” указва само броя парчета от даден тип, а не големината на съответния етикет. Тя се определя с помощта на две полета, а именно “DataCount” и “DataType”. Така например при стойности “08h” за “DataCount” и “03h” за “DataType”, следва че имаме 8 шестнайсетбитови цели числа без знак или общо 32 байта данни.

Полето “DataOffset” е с големина 4 байта и обикновенно съдържа отместването, на което може да открием полезните данни на този етикет. Ако обаче тези данни са точно 4 или по-малко байта, се прилага проста оптимизация и вместо полето да съдържа отместването, то съдържа самите полезни данни.

В таблицата по-долу са указани всички дефинирани публични етикети, както и поддръжката им от версии 4, 5 и 6 на “TIFF” формата:

Име на етикета

Идентификационен номер

Тип на етикета

4.0

5.0

6.0

Artist

315

ASCII

-

*

*

BadFaxLines[1]

326

SHORT or LONG

-

-

-

BitsPerSample

258

SHORT

*

*

*

CellLength

265

SHORT

*

*

*

CellWidth

264

SHORT

*

*

*

CleanFaxData[1]

327

SHORT

-

-

-

ColorMap

320

SHORT

-

*

*

ColorResponseCurve

301

SHORT

*

*

x

ColorResponseUnit

300

SHORT

*

x

x

Compression

259

SHORT

*

*

*

Uncompressed

1

 

*

*

*

CCITT 1D

2

 

*

*

*

CCITT Group 3

3

 

*

*

*

CCITT Group 4

4

 

*

*

*

LZW

5

 

-

*

*

JPEG

6

 

-

-

*

Uncompressed

32771

 

*

x

x

Packbits

32773

 

*

*

*

ConsecutiveBadFaxLines[1]

328

LONG or SHORT

-

-

-

Copyright

33432

ASCII

-

-

*

DateTime

306

ASCII

-

*

*

DocumentName

269

ASCII

*

*

*

DotRange

336

BYTE or SHORT

-

-

*

ExtraSamples

338

BYTE

-

-

*

FillOrder

266

SHORT

*

*

*

FreeByteCounts

289

LONG

*

*

*

FreeOffsets

288

LONG

*

*

*

GrayResponseCurve

291

SHORT

*

*

*

GrayResponseUnit

290

SHORT

*

*

*

HalftoneHints

321

SHORT

-

-

*

HostComputer

316

ASCII

-

*

*

ImageDescription

270

ASCII

*

*

*

ImageHeight

257

SHORT or LONG

*

*

*

ImageWidth

256

SHORT or LONG

*

*

*

InkNames

333

ASCII

-

-

*

InkSet

332

SHORT

-

-

*

JPEGACTTables

521

LONG

-

-

*

JPEGDCTTables

520

LONG

-

-

*

JPEGInterchangeFormat

513

LONG

-

-

*

JPEGInterchangeFormatLength

514

LONG

-

-

*

JPEGLosslessPredictors

517

SHORT

-

-

*

JPEGPointTransforms

518

SHORT

-

-

*

JPEGProc

512

SHORT

-

-

*

JPEGRestartInterval

515

SHORT

-

-

*

JPEGQTables

519

LONG

-

-

*

Make

271

ASCII

*

*

*

MaxSampleValue

281

SHORT

*

*

*

MinSampleValue

280

SHORT

*

*

*

Model

272

ASCII

*

*

*

NewSubFileType

254

LONG

-

*

*

NumberOfInks

334

SHORT

-

-

*

Orientation

274

SHORT

*

*

*

PageName

285

ASCII

*

*

*

PageNumber

297

SHORT

*

*

*

PhotometricInterpretation

262

SHORT

*

*

*

WhiteIsZero

0

 

*

*

*

BlackIsZero

1

 

*

*

*

RGB

2

 

*

*

*

RGB Palette

3

 

-

*

*

Tranparency Mask

4

 

-

-

*

CMYK

5

 

-

-

*

YCbCr

6

 

-

-

*

CIELab

8

 

-

-

*

PlanarConfiguration

284

SHORT

*

*

*

Predictor

317

SHORT

-

*

*

PrimaryChromaticities

319

RATIONAL

-

*

*

ReferenceBlackWhite

532

LONG

-

-

*

ResolutionUnit

296

SHORT

*

*

*

RowsPerStrip

278

SHORT or LONG

*

*

*

SampleFormat

339

SHORT

-

-

*

SamplesPerPixel

277

SHORT

*

*

*

SMaxSampleValue

341

Any

-

-

*

SMinSampleValue

340

Any

-

-

*

Software

305

ASCII

-

*

*

StripByteCounts

279

LONG or SHORT

*

*

*

StripOffsets

273

SHORT or LONG

*

*

*

SubFileType

255

SHORT

*

x

x

T4Options[2]

292

LONG

*

*

*

T6Options[3]

293

LONG

*

*

*

TargetPrinter

337

ASCII

-

-

*

Thresholding

263

SHORT

*

*

*

TileByteCounts

325

SHORT or LONG

-

-

*

TileLength

323

SHORT or LONG

-

-

*

TileOffsets

324

LONG

-

-

*

TileWidth

322

SHORT or LONG

-

-

*

TransferFunction[4]

301

SHORT

-

-

*

TransferRange

342

SHORT

-

-

*

XPosition

286

RATIONAL

*

*

*

XResolution

282

RATIONAL

*

*

*

YCbCrCoefficients

529

RATIONAL

-

-

*

YCbCrPositioning

531

SHORT

-

-

*

YCbCrSubSampling

530

SHORT

-

-

*

YPosition

287

RATIONAL

*

*

*

YResolution

283

RATIONAL

*

*

*

WhitePoint

318

RATIONAL

-

*

*

Звездичката означава, че даденият етикет се поддържа от съответната версия, минусът пък, че не се поддържа, а хиксът, че този етикет е станал излишен. Етикетите означени с [1] са част от “TIFF Class F” и не са дефинирани в “TIFF 6.0”. Някои от етикетите са преименувани във версия 6.0 на формата – етикетът, маркиран с [2], от “Group3Options” на “T4Options”, етикетът [3] от “Group3Options” на “T6Options” и етикетът [4] от “ColorResponseCurve” на “TransferFunction”.

обратно към навигационното меню

Организация на данните в етикетите

В зависимост от вида на изображението съществуват минимален брой етикети, които задължително трябва да се дефинират. Във версия 5.0 тези минимални изисквания бяха събрани в класове, като имаше един базов “Class X” и после в зависимост от типа на изображението се добавяше даден клас – “Class B” за бинарни изображения, “Class G” за изображения в гамата на сивото, “Class P” за изображения с палитра и “Class R” за пълноцветни "RGB” изображения. В последната версия на “TIFF”, а именно 6.0 тези класове са предефинирани в 4 отделни базисни конфигурации. Просто “Class X” съществува в комбинация с всеки от останалите 4 и така се дефинират нужните етикети за всеки тип изображение. Съществува и още един клас, наречен “Class F”, който е предназначен за факсимилета. Той е широко използван и днес, тъй като предлага отлични възможности за съхранение на факс документи. В следващата таблица е даден минималният брой задължителни етикети за различните изображения:

име на класа

идентификатор на етикета

име на етикета

Class B & Class G

254

NewSubfileType

 

256

ImageWidth

 

257

ImageLength

 

258

BitsPerSample

 

259

Compression

 

262

PhotometricInterpretation

 

273

StripOffsets

 

277

SamplesPerPixel

 

278

RowsPerStrip

 

279

StripByteCounts

 

282

XResolution

 

283

YResolution

 

296

ResolutionUnit

 

 

 

следващите класове съдържат горните етикети плюс тези, дефинирани под тях:

 

 

 

Class P

320

ColorMap

Class R

284

PlanarConfiguration

YCbCr

529

YCbCrCoefficients

 

530

YCbCrSubSampling

 

531

YCbCrPositioning

 

532

ReferenceBlackWhite

Class F

326

BadFaxLines

 

327

CleanFaxData

 

328

ConsecutiveBadFaxLines

обратно към навигационното меню

Полезни данни

Вече е известно, че полезните данни в изображението не следват веднага след заглавната част, а могат да бъдат разположени произволно из целия файл. В по-старите версии на формата се ползват така наречените “strips”. Това представляват изрезки от цели редове на растерно изображение. Подобно представяне позволява по-лесно буфериране, по-бърз достъп и по-лесно разместване на битовете във времето за данните на изображението. Изрезките много приличат на използваните вече в други формати парчета, блокове и т.н., но се различават по някои основни показатели. Има три задължителни етикети, които трябва да се дефинират за да е възможно ползването на “strips”. Те са “RowsPerStrip”, “StripOffsets” и “StripByteCounts”. Първото от тези три полета указва броя компресирани редове във всяка изрезка. Максималната стойност на това поле съвпада с максимално позволената големина на “TIFF” изображение, а именно 4 гигабайта. Всички изрезки в едно изображение трябва задължително да използват еднаква схема за компресия, да имат еднакъв брой битове за пиксел, еднакво цветово пространство и т.н. Полето “StripOffsets” е много важно, защото съдържа масив с отместванията до началото на всяка една от изрезките. Именно това е полето, което позволява на полезните данни да бъдат пръснати из целия файл. Последното от задължителните полета е “StripByteCount” и в него се съдържа масив от стойности, които указват големината на всяка изрезка в байтове.

Изниква само един проблем, свързан с изрезките и полетата, които ги дефинират. Например за изображение с 482 реда, което трябва да се раздели в изрезки, всяка от които има по 5 реда, ще се получат 97 изрезки, като 96 от тях ще имат по 5 реда, а една ще е с 2 реда. Така стойността на полето “RowsPerStrip” ще е вярна само за 96 изрезки, но не и за последната. Оказва се обаче, че проблемът е само на пръв поглед, защото всъщност декодерите на “TIFF” файлове не се интересуват от броя редове в изрезките, а от броя байтове в тях. Също е важно да отбележим, че полето “RowsPerStrip” указва максималния възможен брой редове в една изрезка, а не точния им брой в нея.

Предимствата на представянето на изображението като изрезки не са за пренебрегване. Като начало не всички приложения могат да четат цял файл от паметта поради ограниченото й количество. Далеч по-удобно е ползването на изрезки, които постъпват в буфера, прочитат се и освобождават място за следващи. Въпреки че изрезките могат да са по-големи от размера на буфера, вероятно за да поддържат компресирани или некомпресирани редове по-големи от 8 kbit, те не бива да надвишават 64 kbit. Друго предимство се осигурява от таблицата с отмествания, която осигурява по-бърз и по-лесен достъп до отделни части на изображението. Въпреки наличието на изрезки някои “TIFF” файлове все още записват директно цяло изображение, което не е удобно, особено за по-големи такива.

Във версия 6.0 на “TIFF” формата са въведени така наречените “tiles” – плочки. Докато изрезките могат да са само едномерни, то плочките може да се смятат като двумерни изрезки със собствена ширина и дължина. За плочките може да се приеме, че са изображения, съдържащи парче от голямото и така за сглобяването му е нужно само правилното им подреждане. Това е особено полезно при изображения с голяма разделителна способност, защото там информацията е обемна и е трудно да се визуализира цялата, а така с помощта на плочките лесно се визуализира една или няколко от тях. Именно поддръжката на двумерни алгоритми за компресия като “JPEG” позволява въвеждането на тези плочки във “TIFF” спецификацията. Замяната на изрезките с плочки довежда и до появата на 4 нови полета, на мястото на старите три. Те са “TileWidth”, “TileLength”, “TileOffsets” и “TileByteCounts”. Предназначението им е абсолютно идентично с това на техните предшественици за изрезките. Първите две полета дефинират големината на плочката с полезна информация, като стойностите им трябва да са кратни на 16. Формата на тези плочки може да бъде както квадрат, така и правоъгълник. В полето “TileOffsets” има масив с отместванията до началото на всички плочки в изображението. Последното поле “TileByteCounts” съдържа броя байтове във всяка компресирана плочка.

Както при версия 5.0 и тук изниква един проблем, който се оказва обаче лесно решим. Въпреки че стойностите на полетата “TileWidth” и “TileLength” трябва да са кратни на 16, не всички изображения изпълняват това условие. Налага се добавяне на отместване за запълване на плочките до кратни на 16 размери. Важно в такива случаи е да се избере такъв размер на плочките, че добавеното отместване да е минимално.

обратно към навигационното меню

Компресия

Файловият формат “TIFF” поддържа най-много схеми за компресия от разгледаните формати за неподвижни изображения. Възможно е дори добавянето на неподдържан метод за компресия само чрез създаването на етикет за него. Версия 4.0 поддържа само “RLE” и “CCITT T.4 & T.6” компресия. В 5.0 се добавя поддръжка за “LZW” компресия, а в 6.0 – “JPEG” компресия.

обратно към навигационното меню

"Paintbrush File Format (PCX)"

тип на изображението

растерно

брой битове на пиксел

от 1 до 24 бита

компресия

“RLE”

максимален размер на изображението

64Kx64K

създател

“ZSoft”, “Microsoft”

поддържани платформи

“Windows”, “MS-DOS”, “UNIX”

Това е един от най-разпространените формати за съхранение на неподвижни изображения. Началото му датира от създаденото за “MS-DOS” приложение “PC Paintbrush” от “ZSoft” и затова понякога за него се говори като “PC Paintbrush” формат. Подписана спогодба със “ZSoft” позволява на “Microsoft” да внедри формата в своята операционна система и да я използва за приложението си “Microsoft Paintbrush for Windows”. В началото форматът се използвал главно за клипарт изображения, както и за факс документи. Максималният брой цветове бил 16 поради ограниченията на “EGA” адаптера. След навлизането на “VGA” видеокартите форматът се преработва, за да поддържа 256 цвята. Настоящата му версия има възможност за съхранение на 24-битови изображения, което го прави удобен за запазване на всякакъв вид графики, снимки и т.н. Форматът е хардуерно зависим, като от видео контролера зависи и как ще се съхраняват данните – за “EGA” на равнини, а за “VGA” на пиксели. За кодирането се ползва “RLE” схема, която е толкова по-ефективна, колкото по-малко цветове има в изображението.

обратно към навигационното меню

Файлова структура

Файловете от формата “PCX” се делят на три големи части – заглавна, полезни данни и цветова палитра. Обикновено палитрата съдържа 256 цвята, отговарящи на “VGA” графичния адаптер.

обратно към навигационното меню

Заглавна част

Големината й е 128 байта и има следния формат:

typedef struct _PcxHeader {
BYTE Identifier; /* идентификационен номер за “PCX” формата (винаги "0x0A ” ) */
BYTE Version; /* версия */
BYTE Encoding; /* метод на кодиране ( винаги 1 – “RLE”) */
BYTE BitsPerPixel; /* битове на пиксел на равнина*/
WORD XStart; /* начало на изображението по абцисата */
WORD YStart; /* начало на изображението по ординатата */
WORD XEnd; /* край на изображението по абцисата */
WORD YEnd; /* край на изображението по ординатата */
WORD HorzRes; /* хоризантална разделителна способност */
WORD VertRes; /* вертикална разделителна способност */
BYTE Palette[48]; /* палитра за “EGA” графичен адаптер */
BYTE Reserved1; /* запазен (винаги 0) */
BYTE NumBitPlanes; /* брой цветови битови равнини */
WORD BytesPerLine; /* байтове на некодиран ред */
WORD PaletteType; /* информация за цветовата палитра (1 – цветна или монохромна информация; 2 – информация за гамата на сивото ) */
WORD HorzScreenSize; /* хоризонтална големина на екрана, на който е създадено изображението */
WORD VertScreenSize; /* вертикална големина на екрана, на който е създадено изображението */
BYTE Reserved2[54]; /* запазен (поредици от нули за запълване на заглавната част до 128 байта) */
} PCXHEAD;

Възможните стойности на полето “Version” са:

стойност

версия и описание на “PCX”

0

версия 2.5 с фиксирана палитра за “EGA” графичен адаптер

2

версия 2.8 с модифицируема палитра за “EGA” графичен адаптер

3

версия 2.8 без цветова палитра

4

"PC Paintbrush for Windows ”

5

версия 3.0 на "PC Paintbrush ”, "PC Paintbrush Plus ”, "PC Paintbrush Plus for Windows ”, "Publisher's Paintbrush ” и всички 24 битови изображения

Полетата “XStart”, “YStart”, “XEnd” и “YEnd” са въведени с цел визуализация само на информацията, попадаща в прозореца, който очертават.

Полето “Palette” e 48-байтов масив от 8-битови стойности, които образуват “EGA” цветовата палитра. При въвеждането на модифицируемата “EGA” палитра се избират 16 от 64 цвята, които да се използват.

Поддържаните режими за визуализация са следните:

брой равнини

битове на пиксел

брой цветове

видео режим

1

1

2

монохромен

1

2

4

"CGA ”

3

1

8

"EGA ”

4

1

16

"EGA ” и "VGA ”

1

8

256

разширен "VGA ”

3

8

16,777,216

разширен "VGA ” и "XGA ”

обратно към навигационното меню

Цветова палитра

Цветова палитра “EGA” с 16 цвята

Първите версии на “PCX” формата са поддържали само фиксирана “EGA” цветова палитра от 16 цвята. Тя представлява 48-байтов масив от 16 тройки от "RGB” стойности. Всяка тройка се състои от стойности за червения, зеления и синия цвят в диапазона от 0 до 255. Графичните адаптери “EGA” обаче имат само 4 възможни вариации за всеки "RGB” цвят. За тази цел всяка „ RGB ” стойност се измества надясно с шест бита за получаване на точната стойност.

Цветова палитра "CGA” с 4 цвята

Използва се същата фиксирана “EGA” палитра. Двуцветни или изображения с 4 цвята може да се визуализират на такъв адаптер, използвайки една от осем възможни цветови палитри, като всяка от тях има три цвята за обекти и един за фон. Цветьт за фона се съдържа в най-старшите 4 бита от първия байт на “EGA” палитрата и е в диапазона от 0 до 15. Най-старшите три бита от четвъртия байт на цветовата палитра са за цвета на обектите. Те отговарят на следните параметри:

цветност

палитра

яркост

(бит 7)

(бит 6)

(бит 5)

0 (цветно)

0 (жълта)

0 (нормална)

1 (монохромно)

1 (бяла)

1 (по-голяма)

Цветова палитра “VGA” с 256 цвята

При създаването на формата е бил широко разпространен “EGA” графичният адаптер, затова появата на “VGA” довела до промени. Тъй като нямало достатъчно място в заглавната част за “VGA” палитрата, се наложило тя да се позиционира в края на файловата структура. Това довежда до проблеми, тъй като полезните данни могат да са с различна големина и това ще промени началната позиция на палитрата за всеки файл. Налага се използването на отместване от края на файла вместо от началото. За да се провери дали даден файл има “VGA” палитра, трябва да се преброят 769 байта назад от края на файла. Ако байтът на тази позиция има стойност “C0h”, следващите 768 байта са “VGA” палитра. Понякога случайно може да се случи този байт да е с дадената стойност. Тогава най-лесният начин да се установи дали имам e “VGA” палитра или това са просто част от полезните данни е да се провери стойностите на следващите 3 байта, които обикновено са нули, ако имаме “VGA” палитра, тъй като първият цвят от нея е черният. 24-битовите изображения нямат цветова палитра, така че тази проверка за тях отпада. Когато се отчете, че имаме “VGA” палитра, записаната в заглавната част се игнорира. При неправилна визуализация на изображението цветовата палитра може да се изключи, като сменим стойността на полето “Version” на 3.

обратно към навигационното меню

Компресиране на полезните данни

Алгоритъмът, използван тук, е еднобайтово или двубайтово кодиране с променлива дължина на думата. Въпреки че не се постигат високи коефициенти на компресия методът е бърз и лесен за реализация. Ако двата най-старши бита на първия байт са единици, това означава, че се използва “RLE” с 2 байта, като първият съдържа броя повтарящи се пиксели в оставащите 6 бита, а вторият – стойността на повтарящия се пиксел. Така максималният брой повтарящи се пиксели в един “RLE” пакет е 64. Ако пък двата най-старши бита на първия байт са нули, това означава, че се използва “RLE” с 1 байт, като следващият байт се записва само веднъж в декодираната поредица.

обратно към навигационното меню

Декодиране на “PCX” файлов формат

За декодирането на един файл в “PCX” формат е нужно да се изчислят следните неща:

    • широчината на изображението в пиксели – изчислява се, като извадим полетата “XEnd” и “XStart” и прибавим единица;
    • дължината на изображението в редове – изчислява се, като извадим полетата “YEnd” и “YStart” и прибавим единица;
    • броя байтове, нужни за един декодиран ред – налага се, ако декодираната информация ще се съхранява в буфер;
    • броа запълващи байтове на края на всеки ред – получава се, като сравним броя пиксели в некодиран ред с широчината на визуализираното изображение.

Следват стъпките за декодиран e:

  • Прочита се един байт.
  • Ако двата най-старши бита са единици, останалите се маскират като стойността за броя повторения на даден пиксел.
  • Прочита се следващия байт.
  • Записва се стойността му толкова пъти, колкото е указано в маската от първия байт.
  • Ако двата най-старши бита са нули, останалите се маскират като стойността за броя повторения на даден пиксел, който в случая е единица.
  • Записва се стойността на втория байт само веднъж.
  • Повтарят се стъпки от 1 до 6, докато се напълни буферът.

Според “PCX” спецификацията е задължително да има пауза след всеки декодиран ред. Ако това условие не е спазено при самото кодиране, процесът се усложнява неимоверно.

обратно към навигационното меню

Кодиране на полезните данни в “PCX” формата

Данните се четат побайтово, като единствената нужна информация за декодирането е броят байтове в един ред. Алгоритъмът за кодиране е следният:

  • Прочита се байт, съдържащ пиксели от изображението, и се съхранява стойността му.
  • Броячът се покачва с едно.
  • Чете се следващият байт и се проверява дали стойнста му е същата като на предния.
  • Ако е същата, броячът се увеличава с едно.
  • Ако не е и броячът е по-голям от единица, равен е на 63, или е достигнат краят на реда, се маскират двата му най-старши бита и се записва стойността на повторенията.
  • Записва се стойността на пиксела във втория байт.
  • Стъпки от 1 до 6 се повтарят до края на редовете от изображението.

обратно към навигационното меню

Формат на данните в “PCX”

Форматът на декодираните данни зависи от две полета в заглавната част – “BitsPerPixel” и “NumBitPlanes”. Редовете на изображението може да се съхраняват по два начина – по пиксели и по равнини. При съхранението по пиксели се използва последователен запис на стойностите на отделните пиксели, а при това по равнини всеки пиксел се разделя на три компонента – червен, зелен и син и се групират цветови равнини за всеки отделен ред. Ако има само една равнина, информацията се записва пиксел по пиксел в една много дълга поредица до достигане край на реда. Всъщност това не представлява самото изображение, а по-скоро поредица от индексни стойности в цветовата палитра. Колко бита заема един пиксел от реда се определя от полето “BitsPerPixel”. Например ако там е записана стойност единица, в един байт от реда се предават 8 пиксела. Редове с 3 битови равнини са рядкост, но се срещат при 24-битовите “PCX” изображения. Тези пък с 4 битови равнини са характерни за “EGA” графичните адаптери, тъй като при тях освен равнините за трите основни цвята на "RGB” има и четвърта, която определя яркостта на изображението.

обратно към навигационното меню

"Microsoft Windows Metafile (WMF)"

тип на изображението

метафайл

брой битове на пиксел

до 24 бита

компресия

не е приложима

максимален размер на изображението

няма ограничение

създател

“Microsoft”

поддържани платформи

“Windows”

Форматът се използва за съхранение на векторни или растерни изображения за по-късно прехвърляне на други устройства. Въпреки, че официално “WMF” се поддържа само от “Windows”, много други операционни системи го поддържат с цел прехвърляне на информация от една операционна система на друга. Така нареченият “Encapsulated PostScript (EPS)” позволява съхранението на векторно базирани данни в “WMF” формата. Мерната единица тук се нарича “twip” и е равна на една 1440-та част от инча, тоест 720 “twips” са равни на половин инч.

обратно към навигационното меню

Файлова структура

Състои се от заглавна част последвана от един или няколко записа с полезни данни. В заглавната част е описано съдържанието на тези записи, като те сами по себе си са бинарно кодирани с функцията “Graphics Device Interface ( GDI)”. Тя се използва за визуализация както на екрана, така и на друго външно устройство. Когато метафайлът се рендерира изцяло, информацията от всеки запис се използва, за да извика съоветната функция, която да преобрази всеки обект в изображение. Последният запис във всеки файл носи информация за неговия край.

Заглавната част е с големина 18 байта и има следната структура:

typedef struct _WindowsMetaHeader {
WORD FileType; /* местоположение на метафайла (1=памет, 2=твърд диск) */
WORD HeaderSize; /* големина на заглавната част (винаги 9) */
WORD Version; /* версия на ползваната операционна система */
DWORD FileSize; /* големина на целия метафайл */
WORD NumOfObjects; /* брой обекти във файла */
DWORD MaxRecordSize; /* големина на най-големия запис във файла */
WORD NoParameters; /* не се използва (винаги 0) */
} WMFHEAD;

Базисният формат на записите, които следват заглавната част, е следният:

typedef struct _WindowsMetaRecord {
DWORD Size; /* големина на записа ( минимум 3 ) */
WORD Function; /* номер на функцията (дефинирана в "WINDOWS.H ” ) */
WORD Parmeters[ ]; /* параметри на функцията ( съхраняват се в ред обратен на този, по който се пращат на функцията ) */
} WMFRECORD;

При изпълнението на подобен метафайл всеки запис се чете и функцията, която е записана в него, се вика и изпълнява. Основните функции са:

Arc

RealizePalette

SetPolyFillMode

Chord

Rectangle

SetROP2

Ellipse

ResizePalette

SetStretchBltMode

ExcludeClipRect

RestoreDC

SetTextAlign

FloodFill

RoundRect

SetTextCharExtra

IntersectClipRect

SaveDC

SetTextColor

LineTo

ScaleViewportExt

SetTextJustification

MoveTo

ScaleWindowExt

SetViewportExt

OffsetClipRgn

SetBkColor

SetViewportOrg

OffsetViewportOrg

SetBkMode

SetWindowExt

OffsetWindowOrg

SetMapMode

SetWindowOrg

PatBlt

SetMapperFlags

 

Pie

SetPixel

 


В някои формати се случва вместо масив от данни в полето “Parameters[ ]” да има цели структури от данни, които може да са:

AnimatePalette

CreatePatternBrush

Escape

BitBlt

CreatePenIndirect

ExtTextOut

CreateBrushIndirect

CreateRegion

Polygon

CreateFontIndirect

DeleteObject

PolyPolygon

CreatePalette

DrawText

Polyline


С излизането на пазара на “Microsoft Windows 3.0” са добавени някои функции или са променени част от параметрите на вече съществуващите. Тези функции са:

AnimatePalette

Record

DeleteObject

BitBlt

CreatePatternBrush

RealizePalette

CreatePalette

Record

ResizePalette

обратно към навигационното меню

Съвместимост на “WMF” и различните приложения

Повечето приложения, които създават метафайлове, поставят 22-байтова заглавна част на файла. Информацията на тази заглавна част е различна от тази на стандартния метафайл, но е важна за съвместимостта му с други приложения. Структурата на тази част е следната:

typedef struct _WmfSpecialHeader {
DWORD Key; /* идентификатор за специфична заглавна част (винаги "9AC6CDD7h ” ) */
WORD Handle; /* не се използва (винаги 0) */
SHORT Left; /* начало на изображението по абцисата в “twips” */
SHORT Top; /* начало на изображението по ординатата в “twips” */
SHORT Right; /* край на изображението по абцисата в “twips” */
SHORT Bottom; /* край на изображението по ординатата в “twips” */
WORD Inch; /* брой “twips” на инч ( използва се за указване на скалиране; ако е 1440, това значи, че изображението е в оригиналната си разделителна способност ) */
DWORD Reserved; /* запазен (винаги 0) */
WORD Checksum; /* проверка за полетата в заглавната част */
} WMFSPECIAL;

обратно към навигационното меню

Съхраняване на растерни изображения в “WMF” файл

Функцията “BitBlt” се използва за съхранение на растерни изображения в “WMF” файл. Тази функция е модифицирана с излизането на “Microsoft Windows 3.0” и затова може да се държи малко странно на по-стари графични контролери [3, 5].

обратно към навигационното меню