diff -r 59758314f811 -r d4524d6a4472 Symbian3/Examples/guid-6013a680-57f9-415b-8851-c4fa63356636/dib2sprt_8c_source.html --- a/Symbian3/Examples/guid-6013a680-57f9-415b-8851-c4fa63356636/dib2sprt_8c_source.html Fri Jun 11 15:24:34 2010 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,613 +0,0 @@ - - -
- -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 */ -