{"id":625,"date":"2016-10-15T14:48:50","date_gmt":"2016-10-15T14:48:50","guid":{"rendered":"http:\/\/bitmap2lcd.com\/blog\/?p=625"},"modified":"2020-01-29T13:01:04","modified_gmt":"2020-01-29T13:01:04","slug":"glcd-data-compression","status":"publish","type":"post","link":"https:\/\/bitmap2lcd.com\/blog\/glcd-data-compression\/","title":{"rendered":"About GLCD Data Compression"},"content":{"rendered":"\n<p> <em>Bitmap2LCD is a tool for programming small Graphic LCDs in embedded systems.<\/em> <\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"656\" height=\"285\" src=\"https:\/\/bitmap2lcd.com\/blog\/wp-content\/uploads\/2020\/01\/bitmap2lcd_monochrome_compression.jpg\" alt=\"\" class=\"wp-image-2862\" srcset=\"https:\/\/bitmap2lcd.com\/blog\/wp-content\/uploads\/2020\/01\/bitmap2lcd_monochrome_compression.jpg 656w, https:\/\/bitmap2lcd.com\/blog\/wp-content\/uploads\/2020\/01\/bitmap2lcd_monochrome_compression-300x130.jpg 300w, https:\/\/bitmap2lcd.com\/blog\/wp-content\/uploads\/2020\/01\/bitmap2lcd_monochrome_compression-624x271.jpg 624w\" sizes=\"auto, (max-width: 656px) 100vw, 656px\" \/><\/figure>\n\n\n<p><span style=\"color: #808080;\"><em>\u00a0<\/em><\/span><strong><span style=\"color: #ff6600;\">Update V3.9H<\/span><\/strong><\/p>\n<p>A simple <strong>data compression<\/strong> feature, for the\u00a0output of GLCD data arrays is implemented in <strong>Bitmap2LCD<\/strong><\/p>\n<p>This function is only available for\u00a0<strong>monochrome mode and\u00a08 bit output <\/strong>format.<\/p>\n<p>The 8 bit microcontrollers for price sensitive projects are\u00a0circuits with often less onchip memory space than most of the 16 or 32 bit devices.<\/p>\n<p>The target is to save as many as microcontroller flash memory as possible. As tables for full display patterns of for example a 128 x 64 dot matrix LCD\u00a0need 1024 bytes each, the goal\u00a0of this function was\u00a0to save flash space for more code or graphics or\u00a0just to reduce the overall flash capacity and therefore to sink the price of the MCU chip.<\/p>\n<p>The microcontroller firmware has to be able to handle these tables with a special code, which decodes the compressed data. Processing time for decompression has to be allowed.<\/p>\n<p>\u00a0<\/p>\n<p>How does it work ?<\/p>\n<p>Instead of only converting the black and white pixels\u00a0found in\u00a0the work canvas to a linear list of <strong>n<\/strong> bytes, with the data compression method explained here, the data array is split into two separate\u00a0arrays in\u00a0one single\u00a0output file : one as usual for the data\u00a0stream and another for the pointers of each data groups.<\/p>\n<p><a href=\"https:\/\/bitmap2lcd.com\/blog\/wp-content\/uploads\/2013\/01\/Compr1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-626 aligncenter\" src=\"https:\/\/bitmap2lcd.com\/blog\/wp-content\/uploads\/2013\/01\/Compr1.png\" alt=\"Compr1\" width=\"325\" height=\"343\" srcset=\"https:\/\/bitmap2lcd.com\/blog\/wp-content\/uploads\/2013\/01\/Compr1.png 325w, https:\/\/bitmap2lcd.com\/blog\/wp-content\/uploads\/2013\/01\/Compr1-284x300.png 284w\" sizes=\"auto, (max-width: 325px) 100vw, 325px\" \/><\/a><\/p>\n<p>The basic concept of this compression is based on\u00a0making groups of <em>consecutive identical<\/em> data bytes in\u00a0the data array.<\/p>\n<p>\u00a0<\/p>\n<p>Consecutive <span style=\"text-decoration: underline;\">identical<\/span> byte chains, and consecutive <span style=\"text-decoration: underline;\">different<\/span> byte chains are handled, the goal here\u00a0is to save data bytes when a <span style=\"text-decoration: underline;\">consecutive identical byte <\/span>chain is found. While the first pointer of a <span style=\"text-decoration: underline;\">consecutive different bytes<\/span> chain is a loss of one data byte stored as a pointer, a <span style=\"text-decoration: underline;\">consecutive identical byte chain<\/span> of 10 bytes is a win of 8 bytes, the data being written only once in the data array. The count of them is then stored in the pointer byte array part.<\/p>\n<p>The\u00a0maximum count of consecutive data, <span style=\"text-decoration: underline;\">identical<\/span> or <span style=\"text-decoration: underline;\">different<\/span> is limited to 127 ( pointer bits 6 to 0 ). If\u00a0a data count in a group\u00a0reaches 127, a new\u00a0group\u00a0is encoded.<\/p>\n<p><a href=\"https:\/\/bitmap2lcd.com\/blog\/wp-content\/uploads\/2013\/01\/compr2.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-627 aligncenter\" src=\"https:\/\/bitmap2lcd.com\/blog\/wp-content\/uploads\/2013\/01\/compr2.png\" alt=\"compr2\" width=\"358\" height=\"161\" srcset=\"https:\/\/bitmap2lcd.com\/blog\/wp-content\/uploads\/2013\/01\/compr2.png 358w, https:\/\/bitmap2lcd.com\/blog\/wp-content\/uploads\/2013\/01\/compr2-300x134.png 300w\" sizes=\"auto, (max-width: 358px) 100vw, 358px\" \/><\/a><\/p>\n<p>The bit 7 of the pointer byte is the flag for the compression decoder. A 1 (high) is for a chain of <span style=\"text-decoration: underline;\">identical<\/span> data bytes, and a 0 (low) is for an chain of <span style=\"text-decoration: underline;\">different<\/span> data.<\/p>\n<p>\u00a0<\/p>\n<p>When data compression is active, Bitmap2LCD\u00a0converts\u00a0all data and shows the compression rate in the compression statistics <strong>at the end<\/strong> of the output file.<\/p>\n<p>\u00a0<\/p>\n<p>This method of compression\u00a0shows different results in vertical or horizontal orientation conversion, it depends of the LCD graphic !<\/p>\n<p>If possible, before to choose the LCD controller\u00a0and its specific data orientation in Display RAM , you could try both orientations and compare the possible compression ratios.<\/p>\n<p>\u00a0<\/p>\n<p>In the <strong><em>Header Include file<\/em><\/strong>, the example script below shows how to setup the compression table information.<\/p>\n<p><em>( It is an example for a GNU-C compiler for ATMEL AVR family )<\/em><\/p>\n<p>Everything after the tag <strong>[&amp;COMPRESSION]<\/strong> is a script information for the data compression function.<\/p>\n<p>The tag <strong>[&amp;CNAME]<\/strong>\u00a0is replaced\u00a0in the output table name, by the data array name<\/p>\n<p>with\u00a0an additional suffix <strong>_x<\/strong> ( For example : Newfile_x )<\/p>\n<p>The tag <strong>[&amp;CSIZE] is not used yet (v2.3)<\/strong><\/p>\n<p><em>In the Header Include file :<\/em><\/p>\n<p>[&amp;COMPRESSION]<br \/>const prog_uint8_t [&amp;CNAME][&amp;CSIZE] = {<\/p>\n<p><strong>\u00a0Please also check the online forum for\u00a0other topics about this function<\/strong><\/p>\n<p><strong>Compression Decoder Example<\/strong><\/p>\n<p>The\u00a0below\u00a0example of a function in C\u00a0language, decodes compressed data\u00a0arrays\u00a0converted with bitmap2LCD.<\/p>\n<p>It is for an Atmel AVR target MCU with GCC compiler, a T6963C LCD controller ( horizontal byte orientation from left to right )<br \/>No buffer RAM.<\/p>\n<p><em>Note : For LCD module widths greater than 255 dots, x and width variables should be long integers<\/em><\/p>\n<p>\u00a0<\/p>\n<h6>\/\/ T6963 function for <strong><span style=\"text-decoration: underline;\">uncompressed<\/span><\/strong> bitmaps<\/h6>\n<h6>\u00a0<\/h6>\n<h6>void GLCD_Bitmap(unsigned char *bitmap, unsigned char x, unsigned char y, unsigned char width, unsigned char height)<\/h6>\n<h6>{<\/h6>\n<h6>unsigned char val;<\/h6>\n<h6>uint8_t LcdX,LcdY,EndX,EndY;<\/h6>\n<h6>long ip = 0; \/\/ table byte counter<\/h6>\n<h6>LcdX=x; \/\/ LCD dot adress X<\/h6>\n<h6>LcdY=y; \/\/ LCD dot adress Y<\/h6>\n<h6>EndY=y+height-1;<\/h6>\n<h6>EndX=x+width;<\/h6>\n<h6>\u00a0<\/h6>\n<h6>while (LcdY &lt; EndY || LcdX &lt; EndX)<\/h6>\n<h6>{<\/h6>\n<h6>GLCD_GraphicGoTo(LcdX, LcdY);<\/h6>\n<h6>GLCD_WriteDisplayData(pgm_read_byte(bitmap + ip));<\/h6>\n<h6>ip ++;<\/h6>\n<h6>LcdX=LcdX+8;<\/h6>\n<h6>if (( LcdX == EndX ) &amp;&amp; ( LcdY&lt;EndY ))<\/h6>\n<h6>{<\/h6>\n<h6>LcdY++;<\/h6>\n<h6>LcdX=x;<\/h6>\n<h6>}<\/h6>\n<h6>}<\/h6>\n<h6>\u00a0<\/h6>\n<h6>}<\/h6>\n<h6>\u00a0<\/h6>\n<h6>\u00a0<\/h6>\n<h6>\/\/ T6963 function for Bitmap2LCD<span style=\"text-decoration: underline;\"><strong> compressed<\/strong> <\/span>bitmaps<\/h6>\n<h6>\u00a0<\/h6>\n<h6>void GLCD_xBitmap(unsigned char *bitmap, unsigned char *pointer, unsigned char x, unsigned char y, unsigned char width, unsigned char height)<\/h6>\n<h6>{<\/h6>\n<h6>\u00a0<\/h6>\n<h6>unsigned char val;<\/h6>\n<h6>uint8_t p,pv,nb,LcdX,LcdY,EndX,EndY;<\/h6>\n<h6>long ip = 0; \/\/ table byte counter<\/h6>\n<h6>p = 0; \/\/ pointer<\/h6>\n<h6>LcdX=x; \/\/ LCD dot adress X<\/h6>\n<h6>LcdY=y; \/\/ LCD dot adress Y<\/h6>\n<h6>EndY=y+height-1; \/\/ End pixel in Y<\/h6>\n<h6>EndX=x+width; \/\/ End Pixel in X<\/h6>\n<h6>\u00a0<\/h6>\n<h6>while (LcdY &lt; EndY || LcdX &lt; EndX)<\/h6>\n<h6>\u00a0<\/h6>\n<h6>{<\/h6>\n<h6>pv = (int)(pgm_read_byte(pointer + p)); \/\/ read the pointer byte<\/h6>\n<h6>p++;<\/h6>\n<h6>\u00a0<\/h6>\n<h6>if (pv &gt; 128) \/\/ bit 7 is logical high when identical bytes chain, low when different<\/h6>\n<h6>{<\/h6>\n<h6>val = pgm_read_byte(bitmap + ip);<\/h6>\n<h6>ip++;<\/h6>\n<h6>nb = pv &#8211; 128;<\/h6>\n<h6>\u00a0<\/h6>\n<h6>while ( nb &gt; 0 ) \/\/ substract bit 7 value for number of bytes in chain<\/h6>\n<h6>{<\/h6>\n<h6>GLCD_GraphicGoTo(LcdX, LcdY); \/\/ bytes in chain are identical<\/h6>\n<h6>GLCD_WriteDisplayData(val);<\/h6>\n<h6>LcdX=LcdX+8;<\/h6>\n<h6>nb&#8211;;<\/h6>\n<h6>if (( LcdX == EndX ) &amp;&amp; ( LcdY&lt;EndY ))<\/h6>\n<h6>{<\/h6>\n<h6>LcdY++;<\/h6>\n<h6>LcdX =x;<\/h6>\n<h6>}<\/h6>\n<h6>}<\/h6>\n<h6>}<\/h6>\n<h6>else \/\/ bytes in chain are different<\/h6>\n<h6>{<\/h6>\n<h6>while ( pv &gt; 0 )<\/h6>\n<h6>{<\/h6>\n<h6>GLCD_GraphicGoTo(LcdX, LcdY);<\/h6>\n<h6>GLCD_WriteDisplayData(pgm_read_byte(bitmap + ip));<\/h6>\n<h6>ip ++;<\/h6>\n<h6>LcdX=LcdX+8;<\/h6>\n<h6>pv&#8211;;<\/h6>\n<h6>if (( LcdX == EndX ) &amp;&amp; ( LcdY&lt;EndY ))<\/h6>\n<h6>{<\/h6>\n<h6>LcdY++;<\/h6>\n<h6>LcdX=x;<\/h6>\n<h6>}<\/h6>\n<h6>}<\/h6>\n<h6>}<\/h6>\n<h6>}<\/h6>\n<h6>}<\/h6>\n<h6>\u00a0<\/h6>\n<h6>\u00a0<\/h6>\n<h6>\u00a0<\/h6>\n<h6>\u00a0<\/h6>\n<h6>\u00a0<\/h6>\t<div class=\"quickshare-container\">\r\n\t<ul class=\"quickshare-genericons quickshare-effect-round quickshare-effect-expand quickshare-small\">\r\n\t\t<li class=\"quickshare-share\"><\/li> \r\n\t\t<li><a href=\"https:\/\/facebook.com\/sharer.php?u=https%3A%2F%2Fbitmap2lcd.com%2Fblog%2Fglcd-data-compression%2F&amp;t=About+GLCD+Data+Compression+<+Bitmap2LCD+Software+Tool+Blog+%3A%3A+about+GLCD+displays+and+Programming\" target=\"_blank\" title=\"Share on Facebook\"><span class=\"quickshare-facebook\">Facebook<\/span><\/a><\/li>\t\t<li><a href=\"https:\/\/twitter.com\/intent\/tweet?url=https%3A%2F%2Fbitmap2lcd.com%2Fblog%2Fglcd-data-compression%2F&amp;text=About+GLCD+Data+Compression+<+Bitmap2LCD+Software+Tool+Blog+%3A%3A+about+GLCD+displays+and+Programming\" target=\"_blank\" title=\"Share on Twitter\"><span class=\"quickshare-twitter\">Twitter<\/span><\/a><\/li>\t\t<li><a href=\"http:\/\/pinterest.com\/pin\/create\/button\/?url=https%3A%2F%2Fbitmap2lcd.com%2Fblog%2Fglcd-data-compression%2F&amp;media=https%3A%2F%2Fbitmap2lcd.com%2Fblog%2Fwp-content%2Fuploads%2F2020%2F01%2Fbitmap2lcd_monochrome_compression-300x130.jpg&amp;description=Bitmap2LCD+is+a+tool+for+programming+small+Graphic+LCDs+in+embedded+systems.+%C2%A0Update+V3.9H+A+simple+data+compression+feature%2C+for+the%C2%A0output+of+GLCD+data+arrays+is+implemented+in+Bitmap2LCD+This+function+is+only+available+for%C2%A0monochrome+mode+and%C2%A08+bit+output+format.%26hellip%3B\" target=\"_blank\" title=\"Share on Pinterest\"><span class=\"quickshare-pinterest\">Pinterest<\/span><\/a><\/li>\t\t<li><a href=\"http:\/\/linkedin.com\/shareArticle?mini=true&amp;url=https%3A%2F%2Fbitmap2lcd.com%2Fblog%2Fglcd-data-compression%2F&amp;title=About+GLCD+Data+Compression&amp;source=Bitmap2LCD+Software+Tool+Blog+%3A%3A+about+GLCD+displays+and+Programming&amp;summary=Bitmap2LCD+is+a+tool+for+programming+small+Graphic+LCDs+in+embedded+systems.+%C2%A0Update+V3.9H+A+simple+data+compression+feature%2C+for+the%C2%A0output+of+GLCD+data+arrays+is+implemented+in+Bitmap2LCD+This+function+is+only+available+for%C2%A0monochrome+mode+and%C2%A08+bit+output+format.%26hellip%3B\" title=\"Share on Linkedin\" target=\"_blank\"><span class=\"quickshare-linkedin\">Linkedin<\/span><\/a><\/li>\t\t<li><a href=\"https:\/\/plus.google.com\/share?url=https%3A%2F%2Fbitmap2lcd.com%2Fblog%2Fglcd-data-compression%2F\" target=\"_blank\" title=\"Share on Google+\"><span class=\"quickshare-googleplus\">Google+<\/span><\/a><\/li>\t\t\t\t\t\t\t\t<li><a href=\"mailto:?subject=Bitmap2LCD+Software+Tool+Blog+%3A%3A+about+GLCD+displays+and+Programming:+About+GLCD+Data+Compression&amp;body=https%3A%2F%2Fbitmap2lcd.com%2Fblog%2Fglcd-data-compression%2F\" target=\"_blank\" title=\"Share via Email\"><span class=\"quickshare-email\">Email<\/span><\/a><\/li>\t<\/ul>\r\n\t<\/div>\r\n","protected":false},"excerpt":{"rendered":"<p>Bitmap2LCD is a tool for programming small Graphic LCDs in embedded systems. \u00a0Update V3.9H A simple data compression feature, for the\u00a0output of GLCD data arrays is implemented in Bitmap2LCD This function is only available for\u00a0monochrome mode and\u00a08 bit output format. The 8 bit microcontrollers for price sensitive projects are\u00a0circuits with often less onchip memory space [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"categories":[50,253],"tags":[261,270,67,257,259,269,262,258,56,55,266,48,265,264,267,268,271,260,272,273,263],"class_list":["post-625","post","type-post","status-publish","format-standard","hentry","category-convert-a-bitmap-to-glcd","category-glcd-data-compression","tag-code","tag-compression-concept","tag-data-array","tag-data-compression","tag-data-size","tag-dot-matrix-array","tag-flash-memory","tag-flash-size","tag-glcd","tag-graphic-lcd","tag-graphics","tag-image","tag-lcd","tag-mcu","tag-memory-space","tag-pixels","tag-reduce-code-size","tag-reduce-size","tag-save-flash","tag-save-memory-size","tag-size"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/bitmap2lcd.com\/blog\/wp-json\/wp\/v2\/posts\/625","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/bitmap2lcd.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/bitmap2lcd.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/bitmap2lcd.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/bitmap2lcd.com\/blog\/wp-json\/wp\/v2\/comments?post=625"}],"version-history":[{"count":71,"href":"https:\/\/bitmap2lcd.com\/blog\/wp-json\/wp\/v2\/posts\/625\/revisions"}],"predecessor-version":[{"id":2863,"href":"https:\/\/bitmap2lcd.com\/blog\/wp-json\/wp\/v2\/posts\/625\/revisions\/2863"}],"wp:attachment":[{"href":"https:\/\/bitmap2lcd.com\/blog\/wp-json\/wp\/v2\/media?parent=625"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/bitmap2lcd.com\/blog\/wp-json\/wp\/v2\/categories?post=625"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/bitmap2lcd.com\/blog\/wp-json\/wp\/v2\/tags?post=625"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}