diff -r f345bda72bc4 -r 43e37759235e Symbian3/Examples/guid-6013a680-57f9-415b-8851-c4fa63356636/dib2sprt_8c_source.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Symbian3/Examples/guid-6013a680-57f9-415b-8851-c4fa63356636/dib2sprt_8c_source.html Tue Mar 30 16:16:55 2010 +0100 @@ -0,0 +1,613 @@ + + +
+ +00001 /* +00002 * dib2sprt.c +00003 * Copyright (C) 2000-2003 A.J. van Os; Released under GPL +00004 * +00005 * Description: +00006 * Functions to translate dib pictures into sprites +00007 */ +00008 +00009 #include <stdio.h> +00010 #include <string.h> +00011 #include "DeskLib:Error.h" +00012 #include "DeskLib:Sprite.h" +00013 #include "antiword.h" +00014 +00015 #if 0 /* defined(DEBUG) */ +00016 static int iPicCounter = 0; +00017 #endif /* DEBUG */ +00018 +00019 +00020 /* +00021 * iGetByteWidth - compute the number of bytes needed for a row of pixels +00022 */ +00023 static int +00024 iGetByteWidth(const imagedata_type *pImg) +00025 { +00026 switch (pImg->uiBitsPerComponent) { +00027 case 1: +00028 return (pImg->iWidth + 31) / 32 * sizeof(int); +00029 case 4: +00030 return (pImg->iWidth + 7) / 8 * sizeof(int); +00031 case 8: +00032 case 24: +00033 return (pImg->iWidth + 3) / 4 * sizeof(int); +00034 default: +00035 DBG_DEC(pImg->uiBitsPerComponent); +00036 return 0; +00037 } +00038 } /* end of iGetByteWidth */ +00039 +00040 /* +00041 * pCreateBlankSprite - Create a blank sprite. +00042 * +00043 * Create a blank sprite and add a palette if needed +00044 * +00045 * returns a pointer to the sprite when successful, otherwise NULL +00046 */ +00047 static sprite_areainfo * +00048 pCreateBlankSprite(const imagedata_type *pImg, size_t *pSize) +00049 { +00050 sprite_areainfo *pArea; +00051 UCHAR *pucTmp; +00052 size_t tSize; +00053 screen_modeval uMode; +00054 int iIndex, iPaletteEntries; +00055 +00056 TRACE_MSG("pCreateBlankSprite"); +00057 +00058 fail(pImg == NULL); +00059 fail(pSize == NULL); +00060 +00061 switch (pImg->uiBitsPerComponent) { +00062 case 1: +00063 uMode.screen_mode = 18; +00064 iPaletteEntries = 2; +00065 break; +00066 case 4: +00067 uMode.screen_mode = 20; +00068 iPaletteEntries = 16; +00069 break; +00070 case 8: +00071 case 24: +00072 uMode.screen_mode = 21; +00073 iPaletteEntries = 0; +00074 break; +00075 default: +00076 DBG_DEC(pImg->uiBitsPerComponent); +00077 return NULL; +00078 } +00079 fail(iPaletteEntries < 0 || iPaletteEntries > 16); +00080 +00081 /* Get memory for the sprite */ +00082 tSize = sizeof(sprite_areainfo) + +00083 Sprite_MemorySize(pImg->iWidth, pImg->iHeight, uMode, +00084 iPaletteEntries > 0 ? sprite_HASPAL : sprite_HASNOMASKPAL); +00085 DBG_DEC(tSize); +00086 pArea = xmalloc(tSize); +00087 +00088 /* Initialise sprite area */ +00089 pArea->areasize = tSize; +00090 pArea->numsprites = 0; +00091 pArea->firstoffset = sizeof(sprite_areainfo); +00092 pArea->freeoffset = sizeof(sprite_areainfo); +00093 +00094 /* Create a blank sprite */ +00095 Error_CheckFatal(Sprite_Create(pArea, "wordimage", +00096 iPaletteEntries > 0 ? 1 : 0, +00097 pImg->iWidth, pImg->iHeight, uMode)); +00098 +00099 /* Add the palette */ +00100 pucTmp = (UCHAR *)pArea + pArea->firstoffset + sizeof(sprite_header); +00101 for (iIndex = 0; iIndex < iPaletteEntries; iIndex++) { +00102 /* First color */ +00103 *pucTmp++ = 0; +00104 *pucTmp++ = pImg->aucPalette[iIndex][0]; +00105 *pucTmp++ = pImg->aucPalette[iIndex][1]; +00106 *pucTmp++ = pImg->aucPalette[iIndex][2]; +00107 /* Second color */ +00108 *pucTmp++ = 0; +00109 *pucTmp++ = pImg->aucPalette[iIndex][0]; +00110 *pucTmp++ = pImg->aucPalette[iIndex][1]; +00111 *pucTmp++ = pImg->aucPalette[iIndex][2]; +00112 } +00113 +00114 *pSize = tSize; +00115 return pArea; +00116 } /* end of pCreateBlankSprite */ +00117 +00118 /* +00119 * iReduceColor - reduce from 24 bit to 8 bit color +00120 * +00121 * Reduce 24 bit true colors to RISC OS default 256 color palette +00122 * +00123 * returns the resulting color +00124 */ +00125 static int +00126 iReduceColor(int iRed, int iGreen, int iBlue) +00127 { +00128 int iResult; +00129 +00130 iResult = (iBlue & 0x80) ? 0x80 : 0; +00131 iResult |= (iGreen & 0x80) ? 0x40 : 0; +00132 iResult |= (iGreen & 0x40) ? 0x20 : 0; +00133 iResult |= (iRed & 0x80) ? 0x10 : 0; +00134 iResult |= (iBlue & 0x40) ? 0x08 : 0; +00135 iResult |= (iRed & 0x40) ? 0x04 : 0; +00136 iResult |= ((iRed | iGreen | iBlue) & 0x20) ? 0x02 : 0; +00137 iResult |= ((iRed | iGreen | iBlue) & 0x10) ? 0x01 : 0; +00138 return iResult; +00139 } /* end of iReduceColor */ +00140 +00141 /* +00142 * vDecode1bpp - decode an uncompressed 1 bit per pixel image +00143 */ +00144 static void +00145 vDecode1bpp(FILE *pFile, UCHAR *pucData, const imagedata_type *pImg) +00146 { +00147 int iX, iY, iByteWidth, iOffset, iTmp, iEighthWidth, iPadding; +00148 UCHAR ucTmp; +00149 +00150 DBG_MSG("vDecode1bpp"); +00151 +00152 fail(pFile == NULL); +00153 fail(pucData == NULL); +00154 fail(pImg == NULL); +00155 fail(pImg->iColorsUsed < 1 || pImg->iColorsUsed > 2); +00156 +00157 iByteWidth = iGetByteWidth(pImg); +00158 +00159 iEighthWidth = (pImg->iWidth + 7) / 8; +00160 iPadding = ROUND4(iEighthWidth) - iEighthWidth; +00161 +00162 for (iY = pImg->iHeight - 1; iY >= 0; iY--) { +00163 for (iX = 0; iX < iEighthWidth; iX++) { +00164 iTmp = iNextByte(pFile); +00165 if (iTmp == EOF) { +00166 return; +00167 } +00168 /* Reverse the bit order */ +00169 ucTmp = (iTmp & BIT(0)) ? (UCHAR)BIT(7) : 0; +00170 ucTmp |= (iTmp & BIT(1)) ? (UCHAR)BIT(6) : 0; +00171 ucTmp |= (iTmp & BIT(2)) ? (UCHAR)BIT(5) : 0; +00172 ucTmp |= (iTmp & BIT(3)) ? (UCHAR)BIT(4) : 0; +00173 ucTmp |= (iTmp & BIT(4)) ? (UCHAR)BIT(3) : 0; +00174 ucTmp |= (iTmp & BIT(5)) ? (UCHAR)BIT(2) : 0; +00175 ucTmp |= (iTmp & BIT(6)) ? (UCHAR)BIT(1) : 0; +00176 ucTmp |= (iTmp & BIT(7)) ? (UCHAR)BIT(0) : 0; +00177 iOffset = iY * iByteWidth + iX; +00178 *(pucData + iOffset) = ucTmp; +00179 } +00180 (void)tSkipBytes(pFile, iPadding); +00181 } +00182 } /* end of vDecode1bpp */ +00183 +00184 /* +00185 * vDecode4bpp - decode an uncompressed 4 bits per pixel image +00186 */ +00187 static void +00188 vDecode4bpp(FILE *pFile, UCHAR *pucData, const imagedata_type *pImg) +00189 { +00190 int iX, iY, iByteWidth, iOffset, iTmp, iHalfWidth, iPadding; +00191 UCHAR ucTmp; +00192 +00193 DBG_MSG("vDecode4bpp"); +00194 +00195 fail(pFile == NULL); +00196 fail(pucData == NULL); +00197 fail(pImg == NULL); +00198 fail(pImg->iColorsUsed < 1 || pImg->iColorsUsed > 16); +00199 +00200 iByteWidth = iGetByteWidth(pImg); +00201 +00202 iHalfWidth = (pImg->iWidth + 1) / 2; +00203 iPadding = ROUND4(iHalfWidth) - iHalfWidth; +00204 +00205 for (iY = pImg->iHeight - 1; iY >= 0; iY--) { +00206 for (iX = 0; iX < iHalfWidth; iX++) { +00207 iTmp = iNextByte(pFile); +00208 if (iTmp == EOF) { +00209 return; +00210 } +00211 /* Reverse the nibble order */ +00212 ucTmp = (iTmp & 0xf0) >> 4; +00213 ucTmp |= (iTmp & 0x0f) << 4; +00214 iOffset = iY * iByteWidth + iX; +00215 *(pucData + iOffset) = ucTmp; +00216 } +00217 (void)tSkipBytes(pFile, iPadding); +00218 } +00219 } /* end of vDecode4bpp */ +00220 +00221 /* +00222 * vDecode8bpp - decode an uncompressed 8 bits per pixel image +00223 */ +00224 static void +00225 vDecode8bpp(FILE *pFile, UCHAR *pucData, const imagedata_type *pImg) +00226 { +00227 int iX, iY, iByteWidth, iOffset, iIndex, iPadding; +00228 +00229 DBG_MSG("vDecode8bpp"); +00230 +00231 fail(pFile == NULL); +00232 fail(pucData == NULL); +00233 fail(pImg == NULL); +00234 fail(pImg->iColorsUsed < 1 || pImg->iColorsUsed > 256); +00235 +00236 iByteWidth = iGetByteWidth(pImg); +00237 +00238 iPadding = ROUND4(pImg->iWidth) - pImg->iWidth; +00239 +00240 for (iY = pImg->iHeight - 1; iY >= 0; iY--) { +00241 for (iX = 0; iX < pImg->iWidth; iX++) { +00242 iIndex = iNextByte(pFile); +00243 if (iIndex == EOF) { +00244 return; +00245 } +00246 iOffset = iY * iByteWidth + iX; +00247 *(pucData + iOffset) = iReduceColor( +00248 pImg->aucPalette[iIndex][0], +00249 pImg->aucPalette[iIndex][1], +00250 pImg->aucPalette[iIndex][2]); +00251 } +00252 (void)tSkipBytes(pFile, iPadding); +00253 } +00254 } /* end of vDecode8bpp */ +00255 +00256 /* +00257 * vDecode24bpp - decode an uncompressed 24 bits per pixel image +00258 */ +00259 static void +00260 vDecode24bpp(FILE *pFile, UCHAR *pucData, const imagedata_type *pImg) +00261 { +00262 int iX, iY, iTripleWidth, iByteWidth, iOffset, iPadding; +00263 int iRed, iGreen, iBlue; +00264 +00265 DBG_MSG("vDecode24bpp"); +00266 +00267 fail(pFile == NULL); +00268 fail(pucData == NULL); +00269 fail(pImg == NULL); +00270 +00271 iByteWidth = iGetByteWidth(pImg); +00272 +00273 iTripleWidth = pImg->iWidth * 3; +00274 iPadding = ROUND4(iTripleWidth) - iTripleWidth; +00275 +00276 for (iY = pImg->iHeight - 1; iY >= 0; iY--) { +00277 for (iX = 0; iX < pImg->iWidth; iX++) { +00278 iBlue = iNextByte(pFile); +00279 if (iBlue == EOF) { +00280 return; +00281 } +00282 iGreen = iNextByte(pFile); +00283 if (iGreen == EOF) { +00284 return; +00285 } +00286 iRed = iNextByte(pFile); +00287 if (iRed == EOF) { +00288 return; +00289 } +00290 iOffset = iY * iByteWidth + iX; +00291 *(pucData + iOffset) = +00292 iReduceColor(iRed, iGreen, iBlue); +00293 } +00294 (void)tSkipBytes(pFile, iPadding); +00295 } +00296 } /* end of vDecode24bpp */ +00297 +00298 /* +00299 * vDecodeRle4 - decode a RLE compressed 4 bits per pixel image +00300 */ +00301 static void +00302 vDecodeRle4(FILE *pFile, UCHAR *pucData, const imagedata_type *pImg) +00303 { +00304 int iX, iY, iByteWidth, iOffset, iTmp, iHalfWidth; +00305 int iRun, iRunLength, iHalfRun; +00306 BOOL bEOL; +00307 UCHAR ucTmp; +00308 +00309 DBG_MSG("vDecodeRle4"); +00310 +00311 fail(pFile == NULL); +00312 fail(pucData == NULL); +00313 fail(pImg == NULL); +00314 fail(pImg->iColorsUsed < 1 || pImg->iColorsUsed > 16); +00315 +00316 DBG_DEC(pImg->iWidth); +00317 DBG_DEC(pImg->iHeight); +00318 +00319 iByteWidth = iGetByteWidth(pImg); +00320 iHalfWidth = (pImg->iWidth + 1) / 2; +00321 +00322 for (iY = pImg->iHeight - 1; iY >= 0; iY--) { +00323 bEOL = FALSE; +00324 iX = 0; +00325 while (!bEOL) { +00326 iRunLength = iNextByte(pFile); +00327 if (iRunLength == EOF) { +00328 return; +00329 } +00330 if (iRunLength != 0) { +00331 /* +00332 * Encoded packet: +00333 * RunLength pixels, all the "same" value +00334 */ +00335 iTmp = iNextByte(pFile); +00336 if (iTmp == EOF) { +00337 return; +00338 } +00339 /* Reverse the nibble order */ +00340 ucTmp = (iTmp & 0xf0) >> 4; +00341 ucTmp |= (iTmp & 0x0f) << 4; +00342 iHalfRun = (iRunLength + 1) / 2; +00343 for (iRun = 0; iRun < iHalfRun; iRun++) { +00344 if (iX < iHalfWidth) { +00345 iOffset = iY * iByteWidth + iX; +00346 *(pucData + iOffset) = ucTmp; +00347 } +00348 iX++; +00349 } +00350 continue; +00351 } +00352 /* Literal or escape */ +00353 iRunLength = iNextByte(pFile); +00354 if (iRunLength == EOF) { +00355 return; +00356 } +00357 if (iRunLength == 0) { /* End of line escape */ +00358 bEOL = TRUE; +00359 } else if (iRunLength == 1) { /* End of file escape */ +00360 return; +00361 } else if (iRunLength == 2) { /* Delta escape */ +00362 DBG_MSG("RLE4: encountered delta escape"); +00363 return; +00364 } else { /* Literal packet */ +00365 iHalfRun = (iRunLength + 1) / 2; +00366 for (iRun = 0; iRun < iHalfRun; iRun++) { +00367 iTmp = iNextByte(pFile); +00368 if (iTmp == EOF) { +00369 return; +00370 } +00371 /* Reverse the nibble order */ +00372 ucTmp = (iTmp & 0xf0) >> 4; +00373 ucTmp |= (iTmp & 0x0f) << 4; +00374 if (iX < iHalfWidth) { +00375 iOffset = iY * iByteWidth + iX; +00376 *(pucData + iOffset) = ucTmp; +00377 } +00378 iX++; +00379 } +00380 /* Padding if the number of bytes is odd */ +00381 if (odd(iHalfRun)) { +00382 (void)tSkipBytes(pFile, 1); +00383 } +00384 } +00385 } +00386 DBG_DEC_C(iX != iHalfWidth, iX); +00387 } +00388 } /* end of vDecodeRle4 */ +00389 +00390 /* +00391 * vDecodeRle8 - decode a RLE compressed 8 bits per pixel image +00392 */ +00393 static void +00394 vDecodeRle8(FILE *pFile, UCHAR *pucData, const imagedata_type *pImg) +00395 { +00396 int iX, iY, iRun, iRunLength, iOffset, iIndex, iByteWidth; +00397 BOOL bEOL; +00398 +00399 DBG_MSG("vDecodeRle8"); +00400 +00401 fail(pFile == NULL); +00402 fail(pucData == NULL); +00403 fail(pImg == NULL); +00404 fail(pImg->iColorsUsed < 1 || pImg->iColorsUsed > 256); +00405 +00406 DBG_DEC(pImg->iWidth); +00407 DBG_DEC(pImg->iHeight); +00408 +00409 iByteWidth = iGetByteWidth(pImg); +00410 +00411 for (iY = pImg->iHeight - 1; iY >= 0; iY--) { +00412 bEOL = FALSE; +00413 iX = 0; +00414 while (!bEOL) { +00415 iRunLength = iNextByte(pFile); +00416 if (iRunLength == EOF) { +00417 return; +00418 } +00419 if (iRunLength != 0) { +00420 /* +00421 * Encoded packet: +00422 * RunLength pixels, all the same value +00423 */ +00424 iIndex = iNextByte(pFile); +00425 if (iIndex == EOF) { +00426 return; +00427 } +00428 for (iRun = 0; iRun < iRunLength; iRun++) { +00429 if (iX < pImg->iWidth) { +00430 iOffset = iY * iByteWidth + iX; +00431 *(pucData + iOffset) = +00432 iReduceColor( +00433 pImg->aucPalette[iIndex][0], +00434 pImg->aucPalette[iIndex][1], +00435 pImg->aucPalette[iIndex][2]); +00436 } +00437 iX++; +00438 } +00439 continue; +00440 } +00441 /* Literal or escape */ +00442 iRunLength = iNextByte(pFile); +00443 if (iRunLength == EOF) { +00444 return; +00445 } +00446 if (iRunLength == 0) { /* End of line escape */ +00447 bEOL = TRUE; +00448 } else if (iRunLength == 1) { /* End of file escape */ +00449 return; +00450 } else if (iRunLength == 2) { /* Delta escape */ +00451 DBG_MSG("RLE8: encountered delta escape"); +00452 return; +00453 } else { /* Literal packet */ +00454 for (iRun = 0; iRun < iRunLength; iRun++) { +00455 iIndex = iNextByte(pFile); +00456 if (iIndex == EOF) { +00457 return; +00458 } +00459 if (iX < pImg->iWidth) { +00460 iOffset = iY * iByteWidth + iX; +00461 *(pucData + iOffset) = +00462 iReduceColor( +00463 pImg->aucPalette[iIndex][0], +00464 pImg->aucPalette[iIndex][1], +00465 pImg->aucPalette[iIndex][2]); +00466 } +00467 iX++; +00468 } +00469 /* Padding if the number of bytes is odd */ +00470 if (odd(iRunLength)) { +00471 (void)tSkipBytes(pFile, 1); +00472 } +00473 } +00474 } +00475 DBG_DEC_C(iX != pImg->iWidth, iX); +00476 } +00477 } /* end of vDecodeRle8 */ +00478 +00479 #if 0 /* defined(DEBUG) */ +00480 static void +00481 vCopy2File(UCHAR *pucSprite, size_t tSpriteSize) +00482 { +00483 FILE *pOutFile; +00484 int iIndex; +00485 char szFilename[30]; +00486 +00487 sprintf(szFilename, "<Wimp$ScrapDir>.sprt%04d", ++iPicCounter); +00488 pOutFile = fopen(szFilename, "wb"); +00489 if (pOutFile == NULL) { +00490 return; +00491 } +00492 DBG_MSG(szFilename); +00493 for (iIndex = 4; iIndex < (int)tSpriteSize; iIndex++) { +00494 if (putc(pucSprite[iIndex], pOutFile) == EOF) { +00495 break; +00496 } +00497 } +00498 (void)fclose(pOutFile); +00499 vSetFiletype(szFilename, FILETYPE_SPRITE); +00500 } /* end of vCopy2File */ +00501 #endif /* DEBUG */ +00502 +00503 /* +00504 * vDecodeDIB - decode a dib picture +00505 */ +00506 static void +00507 vDecodeDIB(diagram_type *pDiag, FILE *pFile, const imagedata_type *pImg) +00508 { +00509 sprite_areainfo *pSprite; +00510 UCHAR *pucPalette, *pucData; +00511 size_t tSpriteSize; +00512 int iHeaderSize; +00513 +00514 /* Skip the bitmap info header */ +00515 iHeaderSize = (int)ulNextLong(pFile); +00516 (void)tSkipBytes(pFile, iHeaderSize - 4); +00517 /* Skip the colortable */ +00518 if (pImg->uiBitsPerComponent <= 8) { +00519 (void)tSkipBytes(pFile, +00520 pImg->iColorsUsed * ((iHeaderSize > 12) ? 4 : 3)); +00521 } +00522 +00523 /* Create an blank sprite */ +00524 pSprite = pCreateBlankSprite(pImg, &tSpriteSize); +00525 pucPalette = (UCHAR *)pSprite + +00526 pSprite->firstoffset + sizeof(sprite_header); +00527 +00528 /* Add the pixel information */ +00529 switch (pImg->uiBitsPerComponent) { +00530 case 1: +00531 fail(pImg->eCompression != compression_none); +00532 pucData = pucPalette + 2 * 8; +00533 vDecode1bpp(pFile, pucData, pImg); +00534 break; +00535 case 4: +00536 fail(pImg->eCompression != compression_none && +00537 pImg->eCompression != compression_rle4); +00538 pucData = pucPalette + 16 * 8; +00539 if (pImg->eCompression == compression_rle4) { +00540 vDecodeRle4(pFile, pucData, pImg); +00541 } else { +00542 vDecode4bpp(pFile, pucData, pImg); +00543 } +00544 break; +00545 case 8: +00546 fail(pImg->eCompression != compression_none && +00547 pImg->eCompression != compression_rle8); +00548 pucData = pucPalette + 0 * 8; +00549 if (pImg->eCompression == compression_rle8) { +00550 vDecodeRle8(pFile, pucData, pImg); +00551 } else { +00552 vDecode8bpp(pFile, pucData, pImg); +00553 } +00554 break; +00555 case 24: +00556 fail(pImg->eCompression != compression_none); +00557 pucData = pucPalette + 0 * 8; +00558 vDecode24bpp(pFile, pucData, pImg); +00559 break; +00560 default: +00561 DBG_DEC(pImg->uiBitsPerComponent); +00562 break; +00563 } +00564 +00565 #if 0 /* defined(DEBUG) */ +00566 vCopy2File((UCHAR *)pSprite, tSpriteSize); +00567 #endif /* DEBUG */ +00568 +00569 /* Add the sprite to the Draw file */ +00570 vImage2Diagram(pDiag, pImg, +00571 (UCHAR *)pSprite + pSprite->firstoffset, +00572 tSpriteSize - pSprite->firstoffset); +00573 +00574 /* Clean up before you leave */ +00575 pSprite = xfree(pSprite); +00576 } /* end of vDecodeDIB */ +00577 +00578 /* +00579 * bTranslateDIB - translate a DIB picture +00580 * +00581 * This function translates a picture from dib to sprite +00582 * +00583 * return TRUE when sucessful, otherwise FALSE +00584 */ +00585 BOOL +00586 bTranslateDIB(diagram_type *pDiag, FILE *pFile, +00587 ULONG ulFileOffset, const imagedata_type *pImg) +00588 { +00589 /* Seek to start position of DIB data */ +00590 if (!bSetDataOffset(pFile, ulFileOffset)) { +00591 return FALSE; +00592 } +00593 +00594 vDecodeDIB(pDiag, pFile, pImg); +00595 +00596 return TRUE; +00597 } /* end of bTranslateDIB */ +