123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470 |
- /*
- * File : blit.h
- * This file is part of RT-Thread GUI Engine
- * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Change Logs:
- * Date Author Notes
- * 2012-01-24 onelife add one more blit table which exchanges the
- * positions of R and B color components in output
- * 2013-10-04 Bernard porting SDL software render to RT-Thread GUI
- */
- /*
- Simple DirectMedia Layer
- Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the authors be held liable for any damages
- arising from the use of this software.
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute it
- freely, subject to the following restrictions:
- 1. The origin of this software must not be misrepresented; you must not
- claim that you wrote the original software. If you use this software
- in a product, an acknowledgment in the product documentation would be
- appreciated but is not required.
- 2. Altered source versions must be plainly marked as such, and must not be
- misrepresented as being the original software.
- 3. This notice may not be removed or altered from any source distribution.
- */
- #include <rtgui/rtgui.h>
- #include <rtgui/blit.h>
- #include <rtgui/color.h>
- #include <rtgui/region.h>
- #include <rtgui/dc.h>
- #include <string.h>
- /* Lookup tables to expand partial bytes to the full 0..255 range */
- static const rt_uint8_t lookup_0[] =
- {
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
- 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
- 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121,
- 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146,
- 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171,
- 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196,
- 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221,
- 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246,
- 247, 248, 249, 250, 251, 252, 253, 254, 255
- };
- static const rt_uint8_t lookup_1[] =
- {
- 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62,
- 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118,
- 120, 122, 124, 126, 128, 130, 132, 134, 136, 138, 140, 142, 144, 146, 148, 150, 152, 154, 156, 158, 160, 162, 164, 166,
- 168, 170, 172, 174, 176, 178, 180, 182, 184, 186, 188, 190, 192, 194, 196, 198, 200, 202, 204, 206, 208, 210, 212, 214,
- 216, 218, 220, 222, 224, 226, 228, 230, 232, 234, 236, 238, 240, 242, 244, 246, 248, 250, 252, 255
- };
- static const rt_uint8_t lookup_2[] =
- {
- 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64, 68, 72, 76, 80, 85, 89, 93, 97, 101, 105, 109, 113, 117,
- 121, 125, 129, 133, 137, 141, 145, 149, 153, 157, 161, 165, 170, 174, 178, 182, 186, 190, 194, 198, 202, 206, 210, 214, 218,
- 222, 226, 230, 234, 238, 242, 246, 250, 255
- };
- static const rt_uint8_t lookup_3[] =
- {
- 0, 8, 16, 24, 32, 41, 49, 57, 65, 74, 82, 90, 98, 106, 115, 123, 131, 139, 148, 156, 164, 172, 180, 189, 197, 205, 213, 222,
- 230, 238, 246, 255
- };
- static const rt_uint8_t lookup_4[] =
- {
- 0, 17, 34, 51, 68, 85, 102, 119, 136, 153, 170, 187, 204, 221, 238, 255
- };
- static const rt_uint8_t lookup_5[] =
- {
- 0, 36, 72, 109, 145, 182, 218, 255
- };
- static const rt_uint8_t lookup_6[] =
- {
- 0, 85, 170, 255
- };
- static const rt_uint8_t lookup_7[] =
- {
- 0, 255
- };
- static const rt_uint8_t lookup_8[] =
- {
- 255
- };
- const rt_uint8_t* rtgui_blit_expand_byte[9] =
- {
- lookup_0,
- lookup_1,
- lookup_2,
- lookup_3,
- lookup_4,
- lookup_5,
- lookup_6,
- lookup_7,
- lookup_8
- };
- /* 2 bpp to 1 bpp */
- static void rtgui_blit_line_2_1(rt_uint8_t *dst_ptr, rt_uint8_t *src_ptr, int line)
- {
- return;
- }
- /* 3 bpp to 1 bpp */
- static void rtgui_blit_line_3_1(rt_uint8_t *dst_ptr, rt_uint8_t *src_ptr, int line)
- {
- line = line / 3;
- while (line)
- {
- *dst_ptr = (rt_uint8_t)(((*src_ptr & 0x00E00000) >> 16) |
- ((*(src_ptr + 1) & 0x0000E000) >> 11) |
- ((*(src_ptr + 2) & 0x000000C0) >> 6));
- src_ptr += 3;
- dst_ptr ++;
- line --;
- }
- return;
- }
- /* 4 bpp to 1 bpp */
- static void rtgui_blit_line_4_1(rt_uint8_t *dst_ptr, rt_uint8_t *src_ptr, int line)
- {
- struct _color
- {
- rt_uint8_t r, g, b, a;
- } *c;
- c = (struct _color *)src_ptr;
- while (line-- > 0)
- {
- *dst_ptr = (c->r & 0xe0) | (c->g & 0xc0) >> 3 | (c->b & 0xe0) >> 5 ;
- c ++;
- dst_ptr ++;
- }
- }
- /* 1 bpp to 2 bpp */
- static void rtgui_blit_line_1_2(rt_uint8_t *dst_ptr, rt_uint8_t *src_ptr, int line)
- {
- return;
- }
- /* 3 bpp to 2 bpp */
- static void rtgui_blit_line_3_2(rt_uint8_t *dst_ptr, rt_uint8_t *src_ptr, int line)
- {
- rt_uint16_t *dst;
- dst = (rt_uint16_t *)dst_ptr;
- line = line / 3;
- while (line)
- {
- *dst = (((*(src_ptr + 2) << 8) & 0x0000F800) |
- ((*(src_ptr + 1) << 3) & 0x000007E0) |
- ((*src_ptr >> 3) & 0x0000001F));
- src_ptr += 3;
- dst ++;
- line --;
- }
- return;
- }
- /* 4 bpp to 2 bpp (ARGB --> RGB565) */
- static void rtgui_blit_line_4_2(rt_uint8_t *dst_ptr, rt_uint8_t *src_ptr, int line)
- {
- int width = line/4;
- rt_uint32_t *srcp = (rt_uint32_t *) src_ptr;
- rt_uint16_t *dstp = (rt_uint16_t *) dst_ptr;
- /* *INDENT-OFF* */
- DUFFS_LOOP4(
- {
- rt_uint32_t s = *srcp;
- unsigned alpha = s >> 27; /* downscale alpha to 5 bits */
- /* FIXME: Here we special-case opaque alpha since the
- compositioning used (>>8 instead of /255) doesn't handle
- it correctly. Also special-case alpha=0 for speed?
- Benchmark this! */
- if(alpha)
- {
- if(alpha == (255 >> 3))
- {
- *dstp = (rt_uint16_t)((s >> 8 & 0xf800) + (s >> 5 & 0x7e0) + (s >> 3 & 0x1f));
- }
- else
- {
- rt_uint32_t d = *dstp;
- /*
- * convert source and destination to G0RAB65565
- * and blend all components at the same time
- */
- s = ((s & 0xfc00) << 11) + (s >> 8 & 0xf800)
- + (s >> 3 & 0x1f);
- d = (d | d << 16) & 0x07e0f81f;
- d += (s - d) * alpha >> 5;
- d &= 0x07e0f81f;
- *dstp = (rt_uint16_t)(d | d >> 16);
- }
- }
- srcp++;
- dstp++;
- }, width);
- }
- static void rtgui_blit_line_1_3(rt_uint8_t *dst_ptr, rt_uint8_t *src_ptr, int line)
- {
- return;
- }
- #define HI 1
- #define LO 0
- /* Special optimized blit for RGB 5-6-5 --> RGBA 8-8-8-8 */
- static const rt_uint32_t RGB565_RGBA8888_LUT[512] =
- {
- 0x000000ff, 0x00000000, 0x000008ff, 0x00200000,
- 0x000010ff, 0x00400000, 0x000018ff, 0x00610000,
- 0x000020ff, 0x00810000, 0x000029ff, 0x00a10000,
- 0x000031ff, 0x00c20000, 0x000039ff, 0x00e20000,
- 0x000041ff, 0x08000000, 0x00004aff, 0x08200000,
- 0x000052ff, 0x08400000, 0x00005aff, 0x08610000,
- 0x000062ff, 0x08810000, 0x00006aff, 0x08a10000,
- 0x000073ff, 0x08c20000, 0x00007bff, 0x08e20000,
- 0x000083ff, 0x10000000, 0x00008bff, 0x10200000,
- 0x000094ff, 0x10400000, 0x00009cff, 0x10610000,
- 0x0000a4ff, 0x10810000, 0x0000acff, 0x10a10000,
- 0x0000b4ff, 0x10c20000, 0x0000bdff, 0x10e20000,
- 0x0000c5ff, 0x18000000, 0x0000cdff, 0x18200000,
- 0x0000d5ff, 0x18400000, 0x0000deff, 0x18610000,
- 0x0000e6ff, 0x18810000, 0x0000eeff, 0x18a10000,
- 0x0000f6ff, 0x18c20000, 0x0000ffff, 0x18e20000,
- 0x000400ff, 0x20000000, 0x000408ff, 0x20200000,
- 0x000410ff, 0x20400000, 0x000418ff, 0x20610000,
- 0x000420ff, 0x20810000, 0x000429ff, 0x20a10000,
- 0x000431ff, 0x20c20000, 0x000439ff, 0x20e20000,
- 0x000441ff, 0x29000000, 0x00044aff, 0x29200000,
- 0x000452ff, 0x29400000, 0x00045aff, 0x29610000,
- 0x000462ff, 0x29810000, 0x00046aff, 0x29a10000,
- 0x000473ff, 0x29c20000, 0x00047bff, 0x29e20000,
- 0x000483ff, 0x31000000, 0x00048bff, 0x31200000,
- 0x000494ff, 0x31400000, 0x00049cff, 0x31610000,
- 0x0004a4ff, 0x31810000, 0x0004acff, 0x31a10000,
- 0x0004b4ff, 0x31c20000, 0x0004bdff, 0x31e20000,
- 0x0004c5ff, 0x39000000, 0x0004cdff, 0x39200000,
- 0x0004d5ff, 0x39400000, 0x0004deff, 0x39610000,
- 0x0004e6ff, 0x39810000, 0x0004eeff, 0x39a10000,
- 0x0004f6ff, 0x39c20000, 0x0004ffff, 0x39e20000,
- 0x000800ff, 0x41000000, 0x000808ff, 0x41200000,
- 0x000810ff, 0x41400000, 0x000818ff, 0x41610000,
- 0x000820ff, 0x41810000, 0x000829ff, 0x41a10000,
- 0x000831ff, 0x41c20000, 0x000839ff, 0x41e20000,
- 0x000841ff, 0x4a000000, 0x00084aff, 0x4a200000,
- 0x000852ff, 0x4a400000, 0x00085aff, 0x4a610000,
- 0x000862ff, 0x4a810000, 0x00086aff, 0x4aa10000,
- 0x000873ff, 0x4ac20000, 0x00087bff, 0x4ae20000,
- 0x000883ff, 0x52000000, 0x00088bff, 0x52200000,
- 0x000894ff, 0x52400000, 0x00089cff, 0x52610000,
- 0x0008a4ff, 0x52810000, 0x0008acff, 0x52a10000,
- 0x0008b4ff, 0x52c20000, 0x0008bdff, 0x52e20000,
- 0x0008c5ff, 0x5a000000, 0x0008cdff, 0x5a200000,
- 0x0008d5ff, 0x5a400000, 0x0008deff, 0x5a610000,
- 0x0008e6ff, 0x5a810000, 0x0008eeff, 0x5aa10000,
- 0x0008f6ff, 0x5ac20000, 0x0008ffff, 0x5ae20000,
- 0x000c00ff, 0x62000000, 0x000c08ff, 0x62200000,
- 0x000c10ff, 0x62400000, 0x000c18ff, 0x62610000,
- 0x000c20ff, 0x62810000, 0x000c29ff, 0x62a10000,
- 0x000c31ff, 0x62c20000, 0x000c39ff, 0x62e20000,
- 0x000c41ff, 0x6a000000, 0x000c4aff, 0x6a200000,
- 0x000c52ff, 0x6a400000, 0x000c5aff, 0x6a610000,
- 0x000c62ff, 0x6a810000, 0x000c6aff, 0x6aa10000,
- 0x000c73ff, 0x6ac20000, 0x000c7bff, 0x6ae20000,
- 0x000c83ff, 0x73000000, 0x000c8bff, 0x73200000,
- 0x000c94ff, 0x73400000, 0x000c9cff, 0x73610000,
- 0x000ca4ff, 0x73810000, 0x000cacff, 0x73a10000,
- 0x000cb4ff, 0x73c20000, 0x000cbdff, 0x73e20000,
- 0x000cc5ff, 0x7b000000, 0x000ccdff, 0x7b200000,
- 0x000cd5ff, 0x7b400000, 0x000cdeff, 0x7b610000,
- 0x000ce6ff, 0x7b810000, 0x000ceeff, 0x7ba10000,
- 0x000cf6ff, 0x7bc20000, 0x000cffff, 0x7be20000,
- 0x001000ff, 0x83000000, 0x001008ff, 0x83200000,
- 0x001010ff, 0x83400000, 0x001018ff, 0x83610000,
- 0x001020ff, 0x83810000, 0x001029ff, 0x83a10000,
- 0x001031ff, 0x83c20000, 0x001039ff, 0x83e20000,
- 0x001041ff, 0x8b000000, 0x00104aff, 0x8b200000,
- 0x001052ff, 0x8b400000, 0x00105aff, 0x8b610000,
- 0x001062ff, 0x8b810000, 0x00106aff, 0x8ba10000,
- 0x001073ff, 0x8bc20000, 0x00107bff, 0x8be20000,
- 0x001083ff, 0x94000000, 0x00108bff, 0x94200000,
- 0x001094ff, 0x94400000, 0x00109cff, 0x94610000,
- 0x0010a4ff, 0x94810000, 0x0010acff, 0x94a10000,
- 0x0010b4ff, 0x94c20000, 0x0010bdff, 0x94e20000,
- 0x0010c5ff, 0x9c000000, 0x0010cdff, 0x9c200000,
- 0x0010d5ff, 0x9c400000, 0x0010deff, 0x9c610000,
- 0x0010e6ff, 0x9c810000, 0x0010eeff, 0x9ca10000,
- 0x0010f6ff, 0x9cc20000, 0x0010ffff, 0x9ce20000,
- 0x001400ff, 0xa4000000, 0x001408ff, 0xa4200000,
- 0x001410ff, 0xa4400000, 0x001418ff, 0xa4610000,
- 0x001420ff, 0xa4810000, 0x001429ff, 0xa4a10000,
- 0x001431ff, 0xa4c20000, 0x001439ff, 0xa4e20000,
- 0x001441ff, 0xac000000, 0x00144aff, 0xac200000,
- 0x001452ff, 0xac400000, 0x00145aff, 0xac610000,
- 0x001462ff, 0xac810000, 0x00146aff, 0xaca10000,
- 0x001473ff, 0xacc20000, 0x00147bff, 0xace20000,
- 0x001483ff, 0xb4000000, 0x00148bff, 0xb4200000,
- 0x001494ff, 0xb4400000, 0x00149cff, 0xb4610000,
- 0x0014a4ff, 0xb4810000, 0x0014acff, 0xb4a10000,
- 0x0014b4ff, 0xb4c20000, 0x0014bdff, 0xb4e20000,
- 0x0014c5ff, 0xbd000000, 0x0014cdff, 0xbd200000,
- 0x0014d5ff, 0xbd400000, 0x0014deff, 0xbd610000,
- 0x0014e6ff, 0xbd810000, 0x0014eeff, 0xbda10000,
- 0x0014f6ff, 0xbdc20000, 0x0014ffff, 0xbde20000,
- 0x001800ff, 0xc5000000, 0x001808ff, 0xc5200000,
- 0x001810ff, 0xc5400000, 0x001818ff, 0xc5610000,
- 0x001820ff, 0xc5810000, 0x001829ff, 0xc5a10000,
- 0x001831ff, 0xc5c20000, 0x001839ff, 0xc5e20000,
- 0x001841ff, 0xcd000000, 0x00184aff, 0xcd200000,
- 0x001852ff, 0xcd400000, 0x00185aff, 0xcd610000,
- 0x001862ff, 0xcd810000, 0x00186aff, 0xcda10000,
- 0x001873ff, 0xcdc20000, 0x00187bff, 0xcde20000,
- 0x001883ff, 0xd5000000, 0x00188bff, 0xd5200000,
- 0x001894ff, 0xd5400000, 0x00189cff, 0xd5610000,
- 0x0018a4ff, 0xd5810000, 0x0018acff, 0xd5a10000,
- 0x0018b4ff, 0xd5c20000, 0x0018bdff, 0xd5e20000,
- 0x0018c5ff, 0xde000000, 0x0018cdff, 0xde200000,
- 0x0018d5ff, 0xde400000, 0x0018deff, 0xde610000,
- 0x0018e6ff, 0xde810000, 0x0018eeff, 0xdea10000,
- 0x0018f6ff, 0xdec20000, 0x0018ffff, 0xdee20000,
- 0x001c00ff, 0xe6000000, 0x001c08ff, 0xe6200000,
- 0x001c10ff, 0xe6400000, 0x001c18ff, 0xe6610000,
- 0x001c20ff, 0xe6810000, 0x001c29ff, 0xe6a10000,
- 0x001c31ff, 0xe6c20000, 0x001c39ff, 0xe6e20000,
- 0x001c41ff, 0xee000000, 0x001c4aff, 0xee200000,
- 0x001c52ff, 0xee400000, 0x001c5aff, 0xee610000,
- 0x001c62ff, 0xee810000, 0x001c6aff, 0xeea10000,
- 0x001c73ff, 0xeec20000, 0x001c7bff, 0xeee20000,
- 0x001c83ff, 0xf6000000, 0x001c8bff, 0xf6200000,
- 0x001c94ff, 0xf6400000, 0x001c9cff, 0xf6610000,
- 0x001ca4ff, 0xf6810000, 0x001cacff, 0xf6a10000,
- 0x001cb4ff, 0xf6c20000, 0x001cbdff, 0xf6e20000,
- 0x001cc5ff, 0xff000000, 0x001ccdff, 0xff200000,
- 0x001cd5ff, 0xff400000, 0x001cdeff, 0xff610000,
- 0x001ce6ff, 0xff810000, 0x001ceeff, 0xffa10000,
- 0x001cf6ff, 0xffc20000, 0x001cffff, 0xffe20000,
- };
- /* Special optimized blit for RGB 5-6-5 --> ARGB 8-8-8-8 */
- static const rt_uint32_t RGB565_ARGB8888_LUT[512] =
- {
- 0x00000000, 0xff000000, 0x00000008, 0xff002000,
- 0x00000010, 0xff004000, 0x00000018, 0xff006100,
- 0x00000020, 0xff008100, 0x00000029, 0xff00a100,
- 0x00000031, 0xff00c200, 0x00000039, 0xff00e200,
- 0x00000041, 0xff080000, 0x0000004a, 0xff082000,
- 0x00000052, 0xff084000, 0x0000005a, 0xff086100,
- 0x00000062, 0xff088100, 0x0000006a, 0xff08a100,
- 0x00000073, 0xff08c200, 0x0000007b, 0xff08e200,
- 0x00000083, 0xff100000, 0x0000008b, 0xff102000,
- 0x00000094, 0xff104000, 0x0000009c, 0xff106100,
- 0x000000a4, 0xff108100, 0x000000ac, 0xff10a100,
- 0x000000b4, 0xff10c200, 0x000000bd, 0xff10e200,
- 0x000000c5, 0xff180000, 0x000000cd, 0xff182000,
- 0x000000d5, 0xff184000, 0x000000de, 0xff186100,
- 0x000000e6, 0xff188100, 0x000000ee, 0xff18a100,
- 0x000000f6, 0xff18c200, 0x000000ff, 0xff18e200,
- 0x00000400, 0xff200000, 0x00000408, 0xff202000,
- 0x00000410, 0xff204000, 0x00000418, 0xff206100,
- 0x00000420, 0xff208100, 0x00000429, 0xff20a100,
- 0x00000431, 0xff20c200, 0x00000439, 0xff20e200,
- 0x00000441, 0xff290000, 0x0000044a, 0xff292000,
- 0x00000452, 0xff294000, 0x0000045a, 0xff296100,
- 0x00000462, 0xff298100, 0x0000046a, 0xff29a100,
- 0x00000473, 0xff29c200, 0x0000047b, 0xff29e200,
- 0x00000483, 0xff310000, 0x0000048b, 0xff312000,
- 0x00000494, 0xff314000, 0x0000049c, 0xff316100,
- 0x000004a4, 0xff318100, 0x000004ac, 0xff31a100,
- 0x000004b4, 0xff31c200, 0x000004bd, 0xff31e200,
- 0x000004c5, 0xff390000, 0x000004cd, 0xff392000,
- 0x000004d5, 0xff394000, 0x000004de, 0xff396100,
- 0x000004e6, 0xff398100, 0x000004ee, 0xff39a100,
- 0x000004f6, 0xff39c200, 0x000004ff, 0xff39e200,
- 0x00000800, 0xff410000, 0x00000808, 0xff412000,
- 0x00000810, 0xff414000, 0x00000818, 0xff416100,
- 0x00000820, 0xff418100, 0x00000829, 0xff41a100,
- 0x00000831, 0xff41c200, 0x00000839, 0xff41e200,
- 0x00000841, 0xff4a0000, 0x0000084a, 0xff4a2000,
- 0x00000852, 0xff4a4000, 0x0000085a, 0xff4a6100,
- 0x00000862, 0xff4a8100, 0x0000086a, 0xff4aa100,
- 0x00000873, 0xff4ac200, 0x0000087b, 0xff4ae200,
- 0x00000883, 0xff520000, 0x0000088b, 0xff522000,
- 0x00000894, 0xff524000, 0x0000089c, 0xff526100,
- 0x000008a4, 0xff528100, 0x000008ac, 0xff52a100,
- 0x000008b4, 0xff52c200, 0x000008bd, 0xff52e200,
- 0x000008c5, 0xff5a0000, 0x000008cd, 0xff5a2000,
- 0x000008d5, 0xff5a4000, 0x000008de, 0xff5a6100,
- 0x000008e6, 0xff5a8100, 0x000008ee, 0xff5aa100,
- 0x000008f6, 0xff5ac200, 0x000008ff, 0xff5ae200,
- 0x00000c00, 0xff620000, 0x00000c08, 0xff622000,
- 0x00000c10, 0xff624000, 0x00000c18, 0xff626100,
- 0x00000c20, 0xff628100, 0x00000c29, 0xff62a100,
- 0x00000c31, 0xff62c200, 0x00000c39, 0xff62e200,
- 0x00000c41, 0xff6a0000, 0x00000c4a, 0xff6a2000,
- 0x00000c52, 0xff6a4000, 0x00000c5a, 0xff6a6100,
- 0x00000c62, 0xff6a8100, 0x00000c6a, 0xff6aa100,
- 0x00000c73, 0xff6ac200, 0x00000c7b, 0xff6ae200,
- 0x00000c83, 0xff730000, 0x00000c8b, 0xff732000,
- 0x00000c94, 0xff734000, 0x00000c9c, 0xff736100,
- 0x00000ca4, 0xff738100, 0x00000cac, 0xff73a100,
- 0x00000cb4, 0xff73c200, 0x00000cbd, 0xff73e200,
- 0x00000cc5, 0xff7b0000, 0x00000ccd, 0xff7b2000,
- 0x00000cd5, 0xff7b4000, 0x00000cde, 0xff7b6100,
- 0x00000ce6, 0xff7b8100, 0x00000cee, 0xff7ba100,
- 0x00000cf6, 0xff7bc200, 0x00000cff, 0xff7be200,
- 0x00001000, 0xff830000, 0x00001008, 0xff832000,
- 0x00001010, 0xff834000, 0x00001018, 0xff836100,
- 0x00001020, 0xff838100, 0x00001029, 0xff83a100,
- 0x00001031, 0xff83c200, 0x00001039, 0xff83e200,
- 0x00001041, 0xff8b0000, 0x0000104a, 0xff8b2000,
- 0x00001052, 0xff8b4000, 0x0000105a, 0xff8b6100,
- 0x00001062, 0xff8b8100, 0x0000106a, 0xff8ba100,
- 0x00001073, 0xff8bc200, 0x0000107b, 0xff8be200,
- 0x00001083, 0xff940000, 0x0000108b, 0xff942000,
- 0x00001094, 0xff944000, 0x0000109c, 0xff946100,
- 0x000010a4, 0xff948100, 0x000010ac, 0xff94a100,
- 0x000010b4, 0xff94c200, 0x000010bd, 0xff94e200,
- 0x000010c5, 0xff9c0000, 0x000010cd, 0xff9c2000,
- 0x000010d5, 0xff9c4000, 0x000010de, 0xff9c6100,
- 0x000010e6, 0xff9c8100, 0x000010ee, 0xff9ca100,
- 0x000010f6, 0xff9cc200, 0x000010ff, 0xff9ce200,
- 0x00001400, 0xffa40000, 0x00001408, 0xffa42000,
- 0x00001410, 0xffa44000, 0x00001418, 0xffa46100,
- 0x00001420, 0xffa48100, 0x00001429, 0xffa4a100,
- 0x00001431, 0xffa4c200, 0x00001439, 0xffa4e200,
- 0x00001441, 0xffac0000, 0x0000144a, 0xffac2000,
- 0x00001452, 0xffac4000, 0x0000145a, 0xffac6100,
- 0x00001462, 0xffac8100, 0x0000146a, 0xffaca100,
- 0x00001473, 0xffacc200, 0x0000147b, 0xfface200,
- 0x00001483, 0xffb40000, 0x0000148b, 0xffb42000,
- 0x00001494, 0xffb44000, 0x0000149c, 0xffb46100,
- 0x000014a4, 0xffb48100, 0x000014ac, 0xffb4a100,
- 0x000014b4, 0xffb4c200, 0x000014bd, 0xffb4e200,
- 0x000014c5, 0xffbd0000, 0x000014cd, 0xffbd2000,
- 0x000014d5, 0xffbd4000, 0x000014de, 0xffbd6100,
- 0x000014e6, 0xffbd8100, 0x000014ee, 0xffbda100,
- 0x000014f6, 0xffbdc200, 0x000014ff, 0xffbde200,
- 0x00001800, 0xffc50000, 0x00001808, 0xffc52000,
- 0x00001810, 0xffc54000, 0x00001818, 0xffc56100,
- 0x00001820, 0xffc58100, 0x00001829, 0xffc5a100,
- 0x00001831, 0xffc5c200, 0x00001839, 0xffc5e200,
- 0x00001841, 0xffcd0000, 0x0000184a, 0xffcd2000,
- 0x00001852, 0xffcd4000, 0x0000185a, 0xffcd6100,
- 0x00001862, 0xffcd8100, 0x0000186a, 0xffcda100,
- 0x00001873, 0xffcdc200, 0x0000187b, 0xffcde200,
- 0x00001883, 0xffd50000, 0x0000188b, 0xffd52000,
- 0x00001894, 0xffd54000, 0x0000189c, 0xffd56100,
- 0x000018a4, 0xffd58100, 0x000018ac, 0xffd5a100,
- 0x000018b4, 0xffd5c200, 0x000018bd, 0xffd5e200,
- 0x000018c5, 0xffde0000, 0x000018cd, 0xffde2000,
- 0x000018d5, 0xffde4000, 0x000018de, 0xffde6100,
- 0x000018e6, 0xffde8100, 0x000018ee, 0xffdea100,
- 0x000018f6, 0xffdec200, 0x000018ff, 0xffdee200,
- 0x00001c00, 0xffe60000, 0x00001c08, 0xffe62000,
- 0x00001c10, 0xffe64000, 0x00001c18, 0xffe66100,
- 0x00001c20, 0xffe68100, 0x00001c29, 0xffe6a100,
- 0x00001c31, 0xffe6c200, 0x00001c39, 0xffe6e200,
- 0x00001c41, 0xffee0000, 0x00001c4a, 0xffee2000,
- 0x00001c52, 0xffee4000, 0x00001c5a, 0xffee6100,
- 0x00001c62, 0xffee8100, 0x00001c6a, 0xffeea100,
- 0x00001c73, 0xffeec200, 0x00001c7b, 0xffeee200,
- 0x00001c83, 0xfff60000, 0x00001c8b, 0xfff62000,
- 0x00001c94, 0xfff64000, 0x00001c9c, 0xfff66100,
- 0x00001ca4, 0xfff68100, 0x00001cac, 0xfff6a100,
- 0x00001cb4, 0xfff6c200, 0x00001cbd, 0xfff6e200,
- 0x00001cc5, 0xffff0000, 0x00001ccd, 0xffff2000,
- 0x00001cd5, 0xffff4000, 0x00001cde, 0xffff6100,
- 0x00001ce6, 0xffff8100, 0x00001cee, 0xffffa100,
- 0x00001cf6, 0xffffc200, 0x00001cff, 0xffffe200
- };
- static void rtgui_blit_line_2_3(rt_uint8_t *dst_ptr, rt_uint8_t *src_ptr, int line)
- {
- rt_uint16_t *src;
- rt_uint32_t *dst;
- src = (rt_uint16_t *)src_ptr;
- dst = (rt_uint32_t *)dst_ptr;
- line = line / 2;
- while (line)
- {
- *dst++ = RGB565_RGBA8888_LUT[src[LO] * 2] + RGB565_RGBA8888_LUT[src[HI] * 2 + 1];
- line--;
- src ++;
- }
- }
- void rtgui_blit_line_direct(rt_uint8_t *dst_ptr, rt_uint8_t *src_ptr, int line)
- {
- memcpy(dst_ptr, src_ptr, line);
- }
- /* convert 4bpp to 3bpp */
- static void rtgui_blit_line_4_3(rt_uint8_t *dst_ptr, rt_uint8_t *src_ptr, int line)
- {
- line = line / 4;
- while (line)
- {
- *dst_ptr++ = *src_ptr++;
- *dst_ptr++ = *src_ptr++;
- *dst_ptr++ = *src_ptr++;
- src_ptr ++;
- line --;
- }
- }
- static void rtgui_blit_line_1_4(rt_uint8_t *dst_ptr, rt_uint8_t *src_ptr, int line)
- {
- }
- static void rtgui_blit_line_2_4(rt_uint8_t *dst_ptr, rt_uint8_t *src_ptr, int line)
- {
- }
- /* convert 3bpp to 4bpp */
- static void rtgui_blit_line_3_4(rt_uint8_t *dst_ptr, rt_uint8_t *src_ptr, int line)
- {
- line = line / 4;
- while (line)
- {
- *dst_ptr++ = *src_ptr++;
- *dst_ptr++ = *src_ptr++;
- *dst_ptr++ = *src_ptr++;
- *dst_ptr++ = 0;
- line --;
- }
- }
- static const rtgui_blit_line_func _blit_table[5][5] =
- {
- /* 0_0, 1_0, 2_0, 3_0, 4_0 */
- {RT_NULL, RT_NULL, RT_NULL, RT_NULL, RT_NULL },
- /* 0_1, 1_1, 2_1, 3_1, 4_1 */
- {RT_NULL, rtgui_blit_line_direct, rtgui_blit_line_2_1, rtgui_blit_line_3_1, rtgui_blit_line_4_1 },
- /* 0_2, 1_2, 2_2, 3_2, 4_2 */
- {RT_NULL, rtgui_blit_line_1_2, rtgui_blit_line_direct, rtgui_blit_line_3_2, rtgui_blit_line_4_2 },
- /* 0_3, 1_3, 2_3, 3_3, 4_3 */
- {RT_NULL, rtgui_blit_line_1_3, rtgui_blit_line_2_3, rtgui_blit_line_direct, rtgui_blit_line_4_3 },
- /* 0_4, 1_4, 2_4, 3_4, 4_4 */
- {RT_NULL, rtgui_blit_line_1_4, rtgui_blit_line_2_4, rtgui_blit_line_3_4, rtgui_blit_line_direct },
- };
- rtgui_blit_line_func rtgui_blit_line_get(int dst_bpp, int src_bpp)
- {
- RT_ASSERT(dst_bpp > 0 && dst_bpp < 5);
- RT_ASSERT(src_bpp > 0 && src_bpp < 5);
- return _blit_table[dst_bpp][src_bpp];
- }
- static void rtgui_blit_line_3_2_inv(rt_uint8_t *dst_ptr, rt_uint8_t *src_ptr, int line)
- {
- rt_uint16_t *dst;
- dst = (rt_uint16_t *)dst_ptr;
- line = line / 3;
- while (line)
- {
- *dst = (((*src_ptr << 8) & 0x0000F800) |
- ((*(src_ptr + 1) << 3) & 0x000007E0) |
- ((*(src_ptr + 2) >> 3) & 0x0000001F));
- src_ptr += 3;
- dst ++;
- line --;
- }
- return;
- }
- void rtgui_blit_line_2_2_inv(rt_uint8_t *dst_ptr, rt_uint8_t *src_ptr, int line)
- {
- rt_uint16_t *dst, *src;
- dst = (rt_uint16_t *)dst_ptr;
- src = (rt_uint16_t *)src_ptr;
- line = line / 2;
- while (line)
- {
- *dst = ((*src << 11) & 0xF800) | (*src & 0x07E0) | ((*src >> 11) & 0x001F);
- src ++;
- dst ++;
- line --;
- }
- }
- static const rtgui_blit_line_func _blit_table_inv[5][5] =
- {
- /* 0_0, 1_0, 2_0, 3_0, 4_0 */
- {RT_NULL, RT_NULL, RT_NULL, RT_NULL, RT_NULL },
- /* 0_1, 1_1, 2_1, 3_1, 4_1 */
- {RT_NULL, rtgui_blit_line_direct, rtgui_blit_line_2_1, rtgui_blit_line_3_1, rtgui_blit_line_4_1 },
- /* 0_2, 1_2, 2_2, 3_2, 4_2 */
- {RT_NULL, rtgui_blit_line_1_2, rtgui_blit_line_2_2_inv, rtgui_blit_line_3_2_inv, rtgui_blit_line_4_2 },
- /* 0_3, 1_3, 2_3, 3_3, 4_3 */
- {RT_NULL, rtgui_blit_line_1_3, rtgui_blit_line_2_3, rtgui_blit_line_direct, rtgui_blit_line_4_3 },
- /* 0_4, 1_4, 2_4, 3_4, 4_4 */
- {RT_NULL, rtgui_blit_line_1_4, rtgui_blit_line_2_4, rtgui_blit_line_3_4, rtgui_blit_line_direct },
- };
- /* get blit function for BGR565 */
- rtgui_blit_line_func rtgui_blit_line_get_inv(int dst_bpp, int src_bpp)
- {
- RT_ASSERT(dst_bpp > 0 && dst_bpp < 5);
- RT_ASSERT(src_bpp > 0 && src_bpp < 5);
- return _blit_table_inv[dst_bpp][src_bpp];
- }
- /* 16bpp special case for per-surface alpha=50%: blend 2 pixels in parallel */
- /* blend a single 16 bit pixel at 50% */
- #define BLEND16_50(d, s, mask) \
- ((((s & mask) + (d & mask)) >> 1) + (s & d & (~mask & 0xffff)))
- /* blend two 16 bit pixels at 50% */
- #define BLEND2x16_50(d, s, mask) \
- (((s & (mask | mask << 16)) >> 1) + ((d & (mask | mask << 16)) >> 1) \
- + (s & d & (~(mask | mask << 16))))
- static void
- Blit16to16SurfaceAlpha128(struct rtgui_blit_info * info, rt_uint16_t mask)
- {
- int width = info->dst_w;
- int height = info->dst_h;
- rt_uint16_t *srcp = (rt_uint16_t *) info->src;
- int srcskip = info->src_skip >> 1;
- rt_uint16_t *dstp = (rt_uint16_t *) info->dst;
- int dstskip = info->dst_skip >> 1;
- while (height--)
- {
- if (((unsigned int) srcp ^ (unsigned int) dstp) & 2)
- {
- /*
- * Source and destination not aligned, pipeline it.
- * This is mostly a win for big blits but no loss for
- * small ones
- */
- rt_uint32_t prev_sw;
- int w = width;
- /* handle odd destination */
- if ((unsigned int) dstp & 2)
- {
- rt_uint16_t d = *dstp, s = *srcp;
- *dstp = BLEND16_50(d, s, mask);
- dstp++;
- srcp++;
- w--;
- }
- srcp++; /* srcp is now 32-bit aligned */
- /* bootstrap pipeline with first halfword */
- prev_sw = ((rt_uint32_t *) srcp)[-1];
- while (w > 1)
- {
- rt_uint32_t sw, dw, s;
- sw = *(rt_uint32_t *) srcp;
- dw = *(rt_uint32_t *) dstp;
- s = (prev_sw >> 16) + (sw << 16);
- prev_sw = sw;
- *(rt_uint32_t *) dstp = BLEND2x16_50(dw, s, mask);
- dstp += 2;
- srcp += 2;
- w -= 2;
- }
- /* final pixel if any */
- if (w)
- {
- rt_uint16_t d = *dstp, s;
- s = (rt_uint16_t) (prev_sw >> 16);
- *dstp = BLEND16_50(d, s, mask);
- srcp++;
- dstp++;
- }
- srcp += srcskip - 1;
- dstp += dstskip;
- }
- else
- {
- /* source and destination are aligned */
- int w = width;
- /* first odd pixel? */
- if ((unsigned int) srcp & 2)
- {
- rt_uint16_t d = *dstp, s = *srcp;
- *dstp = BLEND16_50(d, s, mask);
- srcp++;
- dstp++;
- w--;
- }
- /* srcp and dstp are now 32-bit aligned */
- while (w > 1)
- {
- rt_uint32_t sw = *(rt_uint32_t *) srcp;
- rt_uint32_t dw = *(rt_uint32_t *) dstp;
- *(rt_uint32_t *) dstp = BLEND2x16_50(dw, sw, mask);
- srcp += 2;
- dstp += 2;
- w -= 2;
- }
- /* last odd pixel? */
- if (w)
- {
- rt_uint16_t d = *dstp, s = *srcp;
- *dstp = BLEND16_50(d, s, mask);
- srcp++;
- dstp++;
- }
- srcp += srcskip;
- dstp += dstskip;
- }
- }
- }
- /* fast RGB565->RGB565 blending with pixel alpha */
- static void
- Blit565to565PixelAlpha(struct rtgui_blit_info * info)
- {
- unsigned alpha = info->a;
- if (alpha == 128)
- {
- Blit16to16SurfaceAlpha128(info, 0xf7de);
- return;
- }
- else if (alpha == 255)
- {
- int len = info->dst_w * 2;
- int height = info->dst_h;
- rt_uint8_t *srcp = info->src;
- rt_uint8_t *dstp = info->dst;
- while (height--)
- {
- memcpy(dstp, srcp, len);
- dstp += info->dst_skip + len;
- srcp += info->src_skip + len;
- }
- return;
- }
- else
- {
- /* R and B only have 5 bits. So 5 bits of alpha is enough. */
- alpha >>= 3;
- }
- if (alpha == 0)
- return;
- {
- int width = info->dst_w / 2;
- int height = info->dst_h;
- rt_uint32_t *srcp = (rt_uint32_t *) info->src;
- rt_uint32_t *dstp = (rt_uint32_t *) info->dst;
- while (height--)
- {
- DUFFS_LOOP8(
- {
- rt_uint32_t s = *srcp++;
- rt_uint32_t d = *dstp;
- rt_uint32_t su = (s << 16) | (s >> 16);
- rt_uint32_t du = (d << 16) | (d >> 16);
- s &= 0x07e0f81f;
- d &= 0x07e0f81f;
- su &= 0x07e0f81f;
- du &= 0x07e0f81f;
- du = ((su - du) * alpha / 32 + du) & 0x07e0f81f;
- d = ((s - d) * alpha / 32 + d) & 0x07e0f81f;
- *dstp++ = (du << 16) | (du >> 16) | d;
- }, width);
- /* Deal with the last pixel. */
- if (info->dst_w % 2)
- {
- rt_uint32_t s = *(rt_uint16_t*)srcp;
- rt_uint32_t d = *(rt_uint16_t*)dstp;
- s = (s | s << 16) & 0x07e0f81f;
- d = (d | d << 16) & 0x07e0f81f;
- d += (s - d) * alpha / 32;
- d &= 0x07e0f81f;
- *(rt_uint16_t*)dstp = (rt_uint16_t)(d | d >> 16);
- srcp = (rt_uint32_t*)((unsigned int)srcp + 2);
- dstp = (rt_uint32_t*)((unsigned int)dstp + 2);
- }
- srcp = (rt_uint32_t*)((unsigned int)srcp + info->src_skip);
- dstp = (rt_uint32_t*)((unsigned int)dstp + info->dst_skip);
- }
- }
- }
- /* fast RGB888->(A)RGB888 blending with surface alpha=128 special case */
- static void BlitRGBtoRGBSurfaceAlpha128(struct rtgui_blit_info *info)
- {
- int width = info->dst_w;
- int height = info->dst_h;
- rt_uint32_t *srcp = (rt_uint32_t *)info->src;
- int srcskip = info->src_skip >> 2;
- rt_uint32_t *dstp = (rt_uint32_t *)info->dst;
- int dstskip = info->dst_skip >> 2;
- while(height--)
- {
- DUFFS_LOOP4(
- {
- rt_uint32_t s = *srcp++;
- rt_uint32_t d = *dstp;
- *dstp++ = ((((s & 0x00fefefe) + (d & 0x00fefefe)) >> 1)
- + (s & d & 0x00010101)) | 0xff000000;
- }, width);
- srcp += srcskip;
- dstp += dstskip;
- }
- }
- /* fast RGB888->(A)RGB888 blending with surface alpha */
- static void BlitRGBtoRGBSurfaceAlpha(struct rtgui_blit_info *info)
- {
- unsigned int alpha = info->a;
- if(alpha == 128)
- {
- BlitRGBtoRGBSurfaceAlpha128(info);
- }
- else
- {
- int width = info->dst_w;
- int height = info->dst_h;
- rt_uint32_t *srcp = (rt_uint32_t *)info->src;
- int srcskip = info->src_skip >> 2;
- rt_uint32_t *dstp = (rt_uint32_t *)info->dst;
- int dstskip = info->dst_skip >> 2;
- while(height--)
- {
- DUFFS_LOOP4(
- {
- rt_uint32_t s;
- rt_uint32_t d;
- rt_uint32_t s1;
- rt_uint32_t d1;
- s = *srcp;
- d = *dstp;
- s1 = s & 0xff00ff;
- d1 = d & 0xff00ff;
- d1 = (d1 + ((s1 - d1) * alpha >> 8))
- & 0xff00ff;
- s &= 0xff00;
- d &= 0xff00;
- d = (d + ((s - d) * alpha >> 8)) & 0xff00;
- *dstp = d1 | d | 0xff000000;
- ++srcp;
- ++dstp;
- }, width);
- srcp += srcskip;
- dstp += dstskip;
- }
- }
- }
- /* fast alpha -> RGB565 blending with pixel alpha */
- static void BlitAlphato565PixelAlpha(struct rtgui_blit_info * info)
- {
- rt_uint32_t srcpixel, dstpixel;
- rt_uint32_t srcR, srcG, srcB, srcA;
- srcR = info->r;
- srcG = info->g;
- srcB = info->b;
- while (info->dst_h--)
- {
- rt_uint8_t *src = (rt_uint8_t *)info->src;
- rt_uint16_t *dst = (rt_uint16_t *)info->dst;
- int n = info->dst_w;
- while (n--)
- {
- srcA = (rt_uint8_t)(*src);
- if (info->a > 0 && info->a != 255)
- srcA = srcA * info->a / 255;
- ARGB8888_FROM_RGBA(srcpixel, srcR, srcG, srcB, srcA);
- /* not do alpha blend */
- if ((srcA >> 3) == (255 >> 3) || info->a == 0)
- {
- dstpixel = srcpixel;
- }
- else if (srcA >> 3 == 0)
- {
- /* keep original pixel data */
- }
- else
- {
- dstpixel = srcpixel;
- }
- if (srcA >> 3 != 0)
- {
- rt_uint32_t s = dstpixel;
- unsigned alpha = s >> 24;
- //alpha = alpha + ((255 - alpha) * alpha) / 255;
- alpha = alpha >> 3;
- if (alpha)
- {
- if (alpha == (255 >> 3))
- {
- *dst = (rt_uint16_t)((s >> 8 & 0xf800) + (s >> 5 & 0x7e0) + (s >> 3 & 0x1f));
- }
- else
- {
- rt_uint32_t d = *dst;
- /*
- * convert source and destination to G0RAB65565
- * and blend all components at the same time
- */
- s = ((s & 0xfc00) << 11) + (s >> 8 & 0xf800)
- + (s >> 3 & 0x1f);
- d = (d | d << 16) & 0x07e0f81f;
- d += (s - d) * alpha >> 5;
- d &= 0x07e0f81f;
- *dst = (rt_uint16_t)(d | d >> 16);
- }
- }
- }
- ++src;
- ++dst;
- }
- info->src += info->src_pitch;
- info->dst += info->dst_pitch;
- }
- }
- /* fast ARGB8888->RGB565 blending with pixel alpha */
- static void BlitARGBto565PixelAlpha(struct rtgui_blit_info * info)
- {
- int width = info->dst_w;
- int height = info->dst_h;
- rt_uint32_t *srcp = (rt_uint32_t *) info->src;
- int srcskip = info->src_skip >> 2;
- rt_uint16_t *dstp = (rt_uint16_t *) info->dst;
- int dstskip = info->dst_skip >> 1;
- while (height--)
- {
- /* *INDENT-OFF* */
- DUFFS_LOOP4(
- {
- rt_uint32_t s = *srcp;
- unsigned alpha = s >> 24;
- if (info->a > 0 && info->a != 255)
- alpha = alpha * info->a / 255;
- alpha = alpha >> 3; /* downscale alpha to 5 bits */
- /* FIXME: Here we special-case opaque alpha since the
- compositioning used (>>8 instead of /255) doesn't handle
- it correctly. Also special-case alpha=0 for speed?
- Benchmark this! */
- if(alpha)
- {
- if(alpha == (255 >> 3) || info->a == 0)
- {
- *dstp = (rt_uint16_t)((s >> 8 & 0xf800) + (s >> 5 & 0x7e0) + (s >> 3 & 0x1f));
- }
- else
- {
- rt_uint32_t d = *dstp;
- /*
- * convert source and destination to G0RAB65565
- * and blend all components at the same time
- */
- s = ((s & 0xfc00) << 11) + (s >> 8 & 0xf800)
- + (s >> 3 & 0x1f);
- d = (d | d << 16) & 0x07e0f81f;
- d += (s - d) * alpha >> 5;
- d &= 0x07e0f81f;
- *dstp = (rt_uint16_t)(d | d >> 16);
- }
- }
- srcp++;
- dstp++;
- }, width);
- /* *INDENT-ON* */
- srcp += srcskip;
- dstp += dstskip;
- }
- }
- /* fast ARGB888->(A)RGB888 blending with pixel alpha */
- static void BlitARGBtoRGBPixelAlpha(struct rtgui_blit_info *info)
- {
- int width = info->dst_w;
- int height = info->dst_h;
- rt_uint32_t *srcp = (rt_uint32_t *)info->src;
- int srcskip = info->src_skip >> 2;
- rt_uint32_t *dstp = (rt_uint32_t *)info->dst;
- int dstskip = info->dst_skip >> 2;
- while(height--)
- {
- DUFFS_LOOP4(
- {
- rt_uint32_t dalpha;
- rt_uint32_t d;
- rt_uint32_t s1;
- rt_uint32_t d1;
- rt_uint32_t s = *srcp;
- rt_uint32_t alpha = s >> 24;
- if (info->a > 0 && info->a != 255)
- alpha = alpha * info->a / 255;
- /* FIXME: Here we special-case opaque alpha since the
- compositioning used (>>8 instead of /255) doesn't handle
- it correctly. Also special-case alpha=0 for speed?
- Benchmark this! */
- if(alpha == 255 || info->a == 0)
- {
- *dstp = (s & 0x00ffffff) | (*dstp & 0xff000000);
- }
- else
- {
- /*
- * take out the middle component (green), and process
- * the other two in parallel. One multiply less.
- */
- d = *dstp;
- dalpha = d & 0xff000000;
- s1 = s & 0xff00ff;
- d1 = d & 0xff00ff;
- d1 = (d1 + ((s1 - d1) * alpha >> 8)) & 0xff00ff;
- s &= 0xff00;
- d &= 0xff00;
- d = (d + ((s - d) * alpha >> 8)) & 0xff00;
- *dstp = d1 | d | dalpha;
- }
- ++srcp;
- ++dstp;
- }, width);
- srcp += srcskip;
- dstp += dstskip;
- }
- }
- static void BlitAlphatoARGB8888PixelAlpha(struct rtgui_blit_info *info)
- {
- rt_uint32_t srcpixel;
- rt_uint32_t srcR, srcG, srcB, srcA;
- rt_uint32_t dstpixel;
- rt_uint32_t dstR, dstG, dstB, dstA;
- srcR = info->r;
- srcG = info->g;
- srcB = info->b;
- while (info->dst_h--)
- {
- rt_uint8_t *src = (rt_uint8_t *)info->src;
- rt_uint32_t *dst = (rt_uint32_t *)info->dst;
- int n = info->dst_w;
- while (n--)
- {
- srcA = (rt_uint8_t)(*src);
- if (info->a > 0 && info->a != 255)
- srcA = srcA * info->a / 255;
- ARGB8888_FROM_RGBA(srcpixel, srcR, srcG, srcB, srcA);
- /* not do alpha blend */
- if (srcA == 255 || info->a == 0)
- {
- *dst = srcpixel;
- }
- else if (srcA >> 3 == 0)
- {
- /* keep original pixel data */
- }
- else
- {
- dstpixel = *dst;
- dstA = (rt_uint8_t)(dstpixel >> 24);
- dstR = (rt_uint8_t)(dstpixel >> 16);
- dstG = (rt_uint8_t)(dstpixel >> 8);
- dstB = (rt_uint8_t)dstpixel;
- if (dstA)
- {
- int alpha = srcA + 1;
- int inverse_alpha = 257 - alpha;
- //alpha = alpha + ((256 - alpha) * alpha) / 256;
- dstR = ((srcR * alpha) + (inverse_alpha * dstR)) >> 8;
- dstG = ((srcG * alpha) + (inverse_alpha * dstG)) >> 8;
- dstB = ((srcB * alpha) + (inverse_alpha * dstB)) >> 8;
- dstA = srcA + ((255 - srcA) * dstA) / 255;
- dstpixel = ((rt_uint32_t)dstA << 24) | ((rt_uint32_t)dstR << 16) | ((rt_uint32_t)dstG << 8) | dstB;
- }
- else
- {
- dstpixel = ((rt_uint32_t)srcA << 24) | ((rt_uint32_t)srcR << 16) | ((rt_uint32_t)srcG << 8) | srcB;
- }
- *dst = dstpixel;
- }
- ++src;
- ++dst;
- }
- info->src += info->src_pitch;
- info->dst += info->dst_pitch;
- }
- }
- static void BlitARGB8888toARGB8888PixelAlpha(struct rtgui_blit_info *info)
- {
- rt_uint32_t srcpixel;
- rt_uint32_t srcR, srcG, srcB, srcA;
- rt_uint32_t dstpixel;
- rt_uint32_t dstR, dstG, dstB, dstA;
- while (info->dst_h--)
- {
- rt_uint32_t *src = (rt_uint32_t *)info->src;
- rt_uint32_t *dst = (rt_uint32_t *)info->dst;
- int n = info->dst_w;
- while (n--)
- {
- srcpixel = *src;
- srcA = (rt_uint8_t)(srcpixel >> 24);
- if (info->a > 0 && info->a != 255)
- srcA = srcA * info->a / 255;
- /* not do alpha blend */
- if (srcA == 255 || info->a == 0)
- {
- *dst = srcpixel;
- }
- else if (srcA == 0)
- {
- /* keep original pixel data */
- }
- else
- {
- srcR = (rt_uint8_t)(srcpixel >> 16);
- srcG = (rt_uint8_t)(srcpixel >> 8);
- srcB = (rt_uint8_t)srcpixel;
- dstpixel = *dst;
- dstA = (rt_uint8_t)(dstpixel >> 24);
- dstR = (rt_uint8_t)(dstpixel >> 16);
- dstG = (rt_uint8_t)(dstpixel >> 8);
- dstB = (rt_uint8_t)dstpixel;
- if (dstA >> 3 != 0)
- {
- int alpha = srcA + 1;
- int inverse_alpha = 257 - alpha;
- dstR = ((srcR * alpha) + (inverse_alpha * dstR)) >> 8;
- dstG = ((srcG * alpha) + (inverse_alpha * dstG)) >> 8;
- dstB = ((srcB * alpha) + (inverse_alpha * dstB)) >> 8;
- dstA = srcA + ((255 - srcA) * dstA) / 255;
- dstpixel = ((rt_uint32_t)dstA << 24) | ((rt_uint32_t)dstR << 16) | ((rt_uint32_t)dstG << 8) | dstB;
- }
- else
- {
- dstpixel = srcpixel;
- }
- *dst = dstpixel;
- }
- ++src;
- ++dst;
- }
- info->src += info->src_pitch;
- info->dst += info->dst_pitch;
- }
- }
- /* Special optimized blit for RGB 5-6-5 --> 32-bit RGB surfaces */
- #define RGB565_32(dst, src, map) (map[src[LO]*2] + map[src[HI]*2+1])
- static void
- BlitRGB565to32(struct rtgui_blit_info *info, const rt_uint32_t *map)
- {
- int width, height;
- rt_uint8_t *src;
- rt_uint32_t *dst;
- int srcskip, dstskip;
- /* Set up some basic variables */
- width = info->dst_w;
- height = info->dst_h;
- src = (rt_uint8_t *) info->src;
- srcskip = info->src_skip;
- dst = (rt_uint32_t *) info->dst;
- dstskip = info->dst_skip / 4;
- while (height--)
- {
- /* *INDENT-OFF* */
- DUFFS_LOOP(
- {
- *dst++ = RGB565_32(dst, src, map);
- src += 2;
- },
- width);
- /* *INDENT-ON* */
- src += srcskip;
- dst += dstskip;
- }
- }
- static void
- BlitRGB565toARGB8888(struct rtgui_blit_info * info)
- {
- BlitRGB565to32(info, RGB565_ARGB8888_LUT);
- }
- void rtgui_blit(struct rtgui_blit_info * info)
- {
- if (info->src_h == 0 ||
- info->src_w == 0 ||
- info->dst_h == 0 ||
- info->dst_w == 0)
- return;
- /* We only use the dst_w in the low level drivers. So adjust the info right
- * here. Note the origin is always (0, 0). */
- if (info->src_w < info->dst_w)
- {
- info->dst_w = info->src_w;
- info->dst_skip = info->dst_pitch - info->dst_w *
- rtgui_color_get_bpp(info->dst_fmt);
- }
- else if (info->src_w > info->dst_w)
- {
- info->src_skip = info->src_pitch - info->dst_w *
- rtgui_color_get_bpp(info->src_fmt);
- }
- if (info->src_h < info->dst_h)
- info->dst_h = info->src_h;
- if (info->src_fmt == RTGRAPHIC_PIXEL_FORMAT_RGB565)
- {
- if (info->dst_fmt == RTGRAPHIC_PIXEL_FORMAT_RGB565)
- Blit565to565PixelAlpha(info);
- else if (info->dst_fmt == RTGRAPHIC_PIXEL_FORMAT_ARGB888)
- BlitRGB565toARGB8888(info);
- }
- else if (info->src_fmt == RTGRAPHIC_PIXEL_FORMAT_ARGB888)
- {
- switch (info->dst_fmt)
- {
- case RTGRAPHIC_PIXEL_FORMAT_RGB565:
- BlitARGBto565PixelAlpha(info);
- break;
- case RTGRAPHIC_PIXEL_FORMAT_RGB888:
- BlitARGBtoRGBPixelAlpha(info);
- break;
- case RTGRAPHIC_PIXEL_FORMAT_ARGB888:
- BlitARGB8888toARGB8888PixelAlpha(info);
- break;
- }
- }
- else if (info->src_fmt == RTGRAPHIC_PIXEL_FORMAT_RGB888)
- {
- if (info->dst_fmt == RTGRAPHIC_PIXEL_FORMAT_ARGB888)
- BlitRGBtoRGBSurfaceAlpha(info);
- }
- else if (info->src_fmt == RTGRAPHIC_PIXEL_FORMAT_ALPHA)
- {
- switch (info->dst_fmt)
- {
- case RTGRAPHIC_PIXEL_FORMAT_RGB565:
- BlitAlphato565PixelAlpha(info);
- break;
- case RTGRAPHIC_PIXEL_FORMAT_RGB888:
- break;
- case RTGRAPHIC_PIXEL_FORMAT_ARGB888:
- BlitAlphatoARGB8888PixelAlpha(info);
- break;
- }
- }
- }
- RTM_EXPORT(rtgui_blit);
- void rtgui_image_info_blit(struct rtgui_image_info *image, struct rtgui_dc *dc, struct rtgui_rect *dc_rect)
- {
- rt_uint8_t bpp, hw_bpp;
- struct rtgui_widget *owner; //目标控件
- struct rtgui_blit_info info = { 0 };
- struct rtgui_rect dest_extent; //相片大小
- struct rtgui_graphic_driver *hw_driver; //目标设备
- hw_driver = rtgui_graphic_driver_get_default(); //获取目标设备指针
- dest_extent = *dc_rect; //接收图片大小值
- if (dc->type == RTGUI_DC_CLIENT && hw_driver->framebuffer)
- {
- int index, num_rects;
- struct rtgui_rect *rects;
- struct rtgui_region dest_region;
- bpp = rtgui_color_get_bpp(image->src_fmt); //获取图片一个像素点数据所占的字节数
- hw_bpp = rtgui_color_get_bpp(hw_driver->pixel_format); //获取目标设备一个像素点数据所占的字节数
- owner = RTGUI_CONTAINER_OF(dc, struct rtgui_widget, dc_type);
- rtgui_widget_rect_to_device(owner, &dest_extent);
- /* get intersect region clip */
- rtgui_region_init_with_extents(&dest_region, &dest_extent);
- rtgui_region_intersect_rect(&dest_region, &(owner->clip), &dest_extent);
- num_rects = rtgui_region_num_rects(&dest_region);
- rects = rtgui_region_rects(&dest_region);
- /* fill common info */
- info.a = image->a;
- info.src_fmt = image->src_fmt;
- info.src_pitch = image->src_pitch;
- info.dst_fmt = hw_driver->pixel_format;
- info.dst_pitch = hw_driver->pitch;
- for (index = 0; index < num_rects; index ++)
- {
- struct rtgui_rect *r = &rects[index];
- /* blit source */
- info.src = image->pixels + (r->x1 - dest_extent.x1) * bpp + (r->y1 - dest_extent.y1) * image->src_pitch;
- info.src_h = rtgui_rect_height(*r);
- info.src_w = rtgui_rect_width(*r);
- info.src_skip = info.src_pitch - info.src_w * bpp;
- /* blit destination */
- info.dst = (rt_uint8_t*)hw_driver->framebuffer + r->y1 * hw_driver->pitch +
- r->x1 * hw_bpp;
- info.dst_h = rtgui_rect_height(*r);
- info.dst_w = rtgui_rect_width(*r);
- info.dst_skip = info.dst_pitch - info.dst_w * hw_bpp;
- rtgui_blit(&info);
- }
- rtgui_region_fini(&dest_region);
- }
- else if (dc->type == RTGUI_DC_HW && hw_driver->framebuffer)
- {
- struct rtgui_dc_hw *hw = (struct rtgui_dc_hw *)dc;
- struct rtgui_rect *r;
- bpp = rtgui_color_get_bpp(image->src_fmt);
- hw_bpp = rtgui_color_get_bpp(hw_driver->pixel_format);
- owner = hw->owner;
- rtgui_widget_rect_to_device(owner, &dest_extent);
- r = &dest_extent;
- /* fill common info */
- info.a = image->a;
- info.src_fmt = image->src_fmt;
- info.src_pitch = image->src_pitch;
- info.dst_fmt = hw_driver->pixel_format;
- info.dst_pitch = hw_driver->pitch;
- /* blit source */
- info.src = image->pixels;
- info.src_h = rtgui_rect_height(*r);
- info.src_w = rtgui_rect_width(*r);
- info.src_skip = info.src_pitch - info.src_w * bpp;
- /* blit destination */
- info.dst = (rt_uint8_t*)hw_driver->framebuffer + r->y1 * hw_driver->pitch + r->x1 * hw_bpp;
- info.dst_h = rtgui_rect_height(*r);
- info.dst_w = rtgui_rect_width(*r);
- info.dst_skip = info.dst_pitch - info.dst_w * hw_bpp;
- rtgui_blit(&info);
- }
- else if (dc->type == RTGUI_DC_BUFFER)
- {
- struct rtgui_rect *r;
- struct rtgui_dc_buffer *dc_buffer = (struct rtgui_dc_buffer*)dc;
- bpp = rtgui_color_get_bpp(image->src_fmt);
- hw_bpp = rtgui_color_get_bpp(dc_buffer->pixel_format);
- r = &dest_extent;
- /* fill common info */
- info.a = image->a;
- info.src_fmt = image->src_fmt;
- info.src_pitch = image->src_pitch;
- info.dst_fmt = dc_buffer->pixel_format;
- info.dst_pitch = dc_buffer->pitch;
- /* blit source */
- info.src = image->pixels;
- info.src_w = rtgui_rect_width(*r);
- info.src_h = rtgui_rect_height(*r);
- info.src_skip = info.src_pitch - info.src_w * bpp;
- /* blit destination */
- info.dst = (rt_uint8_t*)dc_buffer->pixel + r->y1 * dc_buffer->pitch + r->x1 * hw_bpp;
- info.dst_w = rtgui_rect_width(*r);
- info.dst_h = rtgui_rect_height(*r);
- info.dst_skip = info.dst_pitch - info.dst_w * hw_bpp;
- rtgui_blit(&info);
- }
- }
- RTM_EXPORT(rtgui_image_info_blit);
|