00001
00002
00003
00004
00005
00006
00007
00008 #ifndef __SP_IMAGEMANAGEMENT_H__
00009 #define __SP_IMAGEMANAGEMENT_H__
00010
00011
00012 #include "Base/spStandard.hpp"
00013 #include "Base/spInputOutput.hpp"
00014 #include "Base/spMath.hpp"
00015 #include "Base/spMaterialColor.hpp"
00016 #include "FileFormats/Image/spImageFormatInterfaces.hpp"
00017
00018 #include <cstdio>
00019
00020
00021 namespace sp
00022 {
00023 namespace video
00024 {
00025
00026
00027
00028
00029
00030
00031 #define __SP_CONVERT_1_TO_2(src, dest, i, j) \
00032 dest[j+0] = src[i+0]; \
00033 dest[j+1] = DefVal;
00034 #define __SP_CONVERT_1_TO_3(src, dest, i, j) \
00035 dest[j+0] = src[i+0]; \
00036 dest[j+1] = src[i+0]; \
00037 dest[j+2] = src[i+0];
00038 #define __SP_CONVERT_1_TO_4(src, dest, i, j) \
00039 dest[j+0] = src[i+0]; \
00040 dest[j+1] = src[i+0]; \
00041 dest[j+2] = src[i+0]; \
00042 dest[j+3] = DefVal;
00043
00044 #define __SP_CONVERT_2_TO_1(src, dest, i, j) \
00045 dest[j+0] = src[i+0];
00046 #define __SP_CONVERT_2_TO_3(src, dest, i, j) \
00047 dest[j+0] = src[i+0]; \
00048 dest[j+1] = src[i+0]; \
00049 dest[j+2] = src[i+0];
00050 #define __SP_CONVERT_2_TO_4(src, dest, i, j) \
00051 dest[j+0] = src[i+0]; \
00052 dest[j+1] = src[i+0]; \
00053 dest[j+2] = src[i+0]; \
00054 dest[j+3] = src[i+1];
00055
00056 #define __SP_CONVERT_3_TO_1(src, dest, i, j) \
00057 dest[j+0] = ( src[i+0] + src[i+1] + src[i+2] ) / 3;
00058 #define __SP_CONVERT_3_TO_2(src, dest, i, j) \
00059 dest[j+0] = ( src[i+0] + src[i+1] + src[i+2] ) / 3; \
00060 dest[j+1] = DefVal;
00061 #define __SP_CONVERT_3_TO_4(src, dest, i, j) \
00062 dest[j+0] = src[i+0]; \
00063 dest[j+1] = src[i+1]; \
00064 dest[j+2] = src[i+2]; \
00065 dest[j+3] = DefVal;
00066
00067 #define __SP_CONVERT_4_TO_1(src, dest, i, j) \
00068 dest[j+0] = ( src[i+0] + src[i+1] + src[i+2] ) / 3;
00069 #define __SP_CONVERT_4_TO_2(src, dest, i, j) \
00070 dest[j+0] = ( src[i+0] + src[i+1] + src[i+2] ) / 3; \
00071 dest[j+1] = src[i+3];
00072 #define __SP_CONVERT_4_TO_3(src, dest, i, j) \
00073 dest[j+0] = src[i+0]; \
00074 dest[j+1] = src[i+1]; \
00075 dest[j+2] = src[i+2];
00076
00077
00078
00079
00080
00081
00083 enum EImageTurnDegrees
00084 {
00085 TURNDEGREE_90,
00086 TURNDEGREE_180,
00087 TURNDEGREE_270,
00088 };
00089
00090
00091
00092
00093
00094
00095 class Texture;
00096
00101 struct SP_EXPORT SHeightMapTexture
00102 {
00103 SHeightMapTexture();
00104 SHeightMapTexture(const Texture* Tex);
00105 ~SHeightMapTexture();
00106
00107
00108
00110 void createBuffer(const Texture* Tex);
00111
00113 void createBuffer(const dim::size2di &NewSize, s32 NewFormat, const f32* NewImageBuffer);
00114
00116 void clearBuffer();
00117
00124 f32 getHeightValue(const dim::point2df &Pos) const;
00125
00132 dim::vector3df getNormal(const dim::point2df &Pos, const dim::point2df &Adjustment) const;
00133
00134
00135
00136 dim::size2di Size;
00137 f32* ImageBuffer;
00138 };
00139
00140
00142 namespace ImageConverter
00143 {
00144
00145
00146
00147
00148
00150 template <typename T, s32 DefVal> void invertImageColors(T* ImageBuffer, u32 ImageBufferSize);
00151
00153 template <typename T> void flipImageColors(T* ImageBuffer, s32 Width, s32 Height, s32 FormatSize);
00154
00156 template <typename T> void flipImageHorz(T* ImageBuffer, s32 Width, s32 Height, s32 FormatSize);
00157
00159 template <typename T> void flipImageVert(T* ImageBuffer, s32 Width, s32 Height, s32 FormatSize);
00160
00162 template <typename T> void scaleImage(
00163 const T* SrcImageBuffer, s32 SrcWidth, s32 SrcHeight, T* DestImageBuffer, s32 DestWidth, s32 DestHeight, s32 FormatSize
00164 );
00165
00167 template <typename T> void scaleImage(T* &ImageBuffer, s32 Width, s32 Height, s32 NewWidth, s32 NewHeight, s32 FormatSize);
00168
00170 template <typename T> void halveImage(T* &ImageBuffer, s32 Width, s32 Height, s32 FormatSize);
00171
00173 template <typename T, s32 DefVal> void convertImageFormat(T* &ImageBuffer, s32 Width, s32 Height, s32 OldFormatSize, s32 NewFormatSize);
00174
00176 template <typename T> void blurImage(T* &ImageBuffer, s32 Width, s32 Height, s32 FormatSize);
00177
00179 template <typename T> void turnImage(T* ImageBuffer, s32 Width, s32 Height, s32 FormatSize, const EImageTurnDegrees Degree);
00180
00185 template <typename T, s32 DefVal> void convertImageGrayToAlpha(T* ImageBuffer, s32 Width, s32 Height);
00186
00200 template <typename T> bool appendImageBufferBottom(
00201 T* &ImageBuffer, const T* AdditionalBuffer, s32 Width, s32 Height, s32 FrameWidth, s32 FrameHeight, s32 FormatSize
00202 );
00203
00210 template <typename T> bool appendImageBufferRight(
00211 T* &ImageBuffer, const T* AdditionalBuffer, s32 Width, s32 Height, s32 FrameWidth, s32 FrameHeight, s32 FormatSize
00212 );
00213
00223 SP_EXPORT void setImageColorKey(u8* ImageBuffer, s32 Width, s32 Height, const video::color &Color, s32 Tolerance = 0);
00224
00226 SP_EXPORT bool checkImageSize(dim::size2di &InputSize);
00227
00229 SP_EXPORT s32 getMipmapLevelsCount(s32 Width, s32 Height);
00230
00231
00232
00233
00234
00235
00236 template <typename T, s32 DefVal> void invertImageColors(T* ImageBuffer, u32 ImageBufferSize)
00237 {
00238 if (ImageBuffer)
00239 {
00240 for (u32 i = 0; i < ImageBufferSize; ++i)
00241 ImageBuffer[i] = static_cast<T>(DefVal) - ImageBuffer[i];
00242 }
00243 #ifdef SP_DEBUGMODE
00244 else
00245 io::Log::debug("ImageConverter::invertImageColors");
00246 #endif
00247 }
00248
00249 template <typename T> void flipImageColors(T* ImageBuffer, s32 Width, s32 Height, s32 FormatSize)
00250 {
00251 if ( ImageBuffer && Width > 0 && Height > 0 && ( FormatSize == 3 || FormatSize == 4 ) )
00252 {
00253 const u32 ImageBufferSize = Width * Height * FormatSize;
00254
00255 for (u32 i = 0; i < ImageBufferSize; i += FormatSize)
00256 math::Swap<T>(ImageBuffer[i], ImageBuffer[i + 2]);
00257 }
00258 #ifdef SP_DEBUGMODE
00259 else
00260 io::Log::debug("ImageConverter::flipImageColors");
00261 #endif
00262 }
00263
00264 template <typename T> void flipImageHorz(T* ImageBuffer, s32 Width, s32 Height, s32 FormatSize)
00265 {
00266
00267 if (!ImageBuffer || Width <= 0 || Height <= 0 || FormatSize < 1 || FormatSize > 4)
00268 {
00269 #ifdef SP_DEBUGMODE
00270 io::Log::debug("ImageConverter::flipImageHorz");
00271 #endif
00272 return;
00273 }
00274
00275
00276 const s32 Pitch = Width * FormatSize;
00277 const s32 HalfPitch = Pitch/2;
00278
00279
00280 for (s32 y = 0, x; y < Height; ++y)
00281 {
00282 for (x = 0; x < HalfPitch; x += 3)
00283 {
00284 math::Swap<T>(ImageBuffer[ y*Pitch + ( Pitch - x - 1 ) - 0 ], ImageBuffer[ y*Pitch + x + 2 ]);
00285 math::Swap<T>(ImageBuffer[ y*Pitch + ( Pitch - x - 1 ) - 1 ], ImageBuffer[ y*Pitch + x + 1 ]);
00286 math::Swap<T>(ImageBuffer[ y*Pitch + ( Pitch - x - 1 ) - 2 ], ImageBuffer[ y*Pitch + x + 0 ]);
00287 }
00288 }
00289 }
00290
00291 template <typename T> void flipImageVert(T* ImageBuffer, s32 Width, s32 Height, s32 FormatSize)
00292 {
00293
00294 if (!ImageBuffer || Width <= 0 || Height <= 0 || FormatSize < 1 || FormatSize > 4)
00295 {
00296 #ifdef SP_DEBUGMODE
00297 io::Log::debug("ImageConverter::flipImageVert");
00298 #endif
00299 return;
00300 }
00301
00302
00303 const s32 Pitch = Width*FormatSize;
00304 const s32 HalfHeight = Height/2;
00305
00306
00307 for (s32 y = 0, x; y < HalfHeight; ++y)
00308 {
00309 for (x = 0; x < Pitch; ++x)
00310 math::Swap<T>(ImageBuffer[ (Height - y - 1)*Pitch + x ], ImageBuffer[ y*Pitch + x ]);
00311 }
00312 }
00313
00314 template <typename T> void scaleImage(T* &ImageBuffer, s32 Width, s32 Height, s32 NewWidth, s32 NewHeight, s32 FormatSize)
00315 {
00316
00317 if (Width == NewWidth && Height == NewHeight)
00318 return;
00319
00320
00321 if (!ImageBuffer || Width <= 0 || Height <= 0 || NewWidth <= 0 || NewHeight <= 0 || FormatSize < 1 || FormatSize > 4)
00322 {
00323 #ifdef SP_DEBUGMODE
00324 io::Log::debug("ImageConverter::scaleImage");
00325 #endif
00326 return;
00327 }
00328
00329
00330 const u32 ImageBufferSize = NewWidth * NewHeight * FormatSize;
00331
00332 T* NewImageBuffer = new T[ImageBufferSize];
00333
00334 scaleImage<T>(ImageBuffer, Width, Height, NewImageBuffer, NewWidth, NewHeight, FormatSize);
00335
00336
00337 delete [] ImageBuffer;
00338 ImageBuffer = NewImageBuffer;
00339 }
00340
00341 template <typename T> void scaleImage(
00342 const T* SrcImageBuffer, s32 SrcWidth, s32 SrcHeight, T* DestImageBuffer, s32 DestWidth, s32 DestHeight, s32 FormatSize)
00343 {
00344
00345 if ( SrcImageBuffer || !DestImageBuffer || SrcWidth <= 0 || SrcHeight <= 0 ||
00346 DestWidth <= 0 || DestHeight <= 0 || FormatSize < 1 || FormatSize > 4 )
00347 {
00348 #ifdef SP_DEBUGMODE
00349 io::Log::debug("ImageConverter::scaleImage");
00350 #endif
00351 return;
00352 }
00353
00354
00355 s32 x, y, i, j, k;
00356
00357
00358 for (y = 0; y < DestHeight; ++y)
00359 {
00360 for (x = 0; x < DestWidth; ++x)
00361 {
00362 for (i = 0; i < FormatSize; ++i)
00363 {
00364
00365 j = y * DestWidth + x;
00366 k = ( y * SrcHeight / DestHeight ) * SrcWidth + ( x * SrcWidth / DestWidth );
00367
00368
00369 DestImageBuffer[ j * FormatSize + i ] = SrcImageBuffer[ k * FormatSize + i ];
00370 }
00371 }
00372 }
00373 }
00374
00375 template <typename T> void halveImage(T* &ImageBuffer, s32 Width, s32 Height, s32 FormatSize)
00376 {
00377
00378 if (!ImageBuffer || Width <= 0 || Height <= 0 || FormatSize < 1 || FormatSize > 4)
00379 {
00380 #ifdef SP_DEBUGMODE
00381 io::Log::debug("ImageConverter::halveImage");
00382 #endif
00383 return;
00384 }
00385
00386
00387 s32 x, y, i, x2, y2;
00388
00389
00390 s32 NewWidth = Width;
00391 s32 NewHeight = Height;
00392
00393
00394 if (NewWidth > 1)
00395 NewWidth >>= 1;
00396 if (NewHeight > 1)
00397 NewHeight >>= 1;
00398
00399
00400 T* OldImageBuffer = ImageBuffer;
00401
00402
00403 ImageBuffer = new T[ NewWidth * NewHeight * FormatSize ];
00404
00405 if (Width > 1 && Height > 1)
00406 {
00407
00408
00409 for (y = y2 = 0; y < NewHeight; ++y, y2 = y << 1)
00410 {
00411 for (x = x2 = 0; x < NewWidth; ++x, x2 = x << 1)
00412 {
00413 for (i = 0; i < FormatSize; ++i)
00414 {
00415
00416 ImageBuffer[ ( y * NewWidth + x ) * FormatSize + i ] = (
00417 OldImageBuffer[ ( (y2 ) * Width + (x2 ) ) * FormatSize + i ] +
00418 OldImageBuffer[ ( (y2 ) * Width + (x2 + 1) ) * FormatSize + i ] +
00419 OldImageBuffer[ ( (y2 + 1) * Width + (x2 ) ) * FormatSize + i ] +
00420 OldImageBuffer[ ( (y2 + 1) * Width + (x2 + 1) ) * FormatSize + i ]
00421 ) / 4;
00422 }
00423 }
00424 }
00425
00426 }
00427 else if (Width == 1 || Height == 1)
00428 {
00429
00430 s32 MaxSize = math::Max(NewWidth, NewHeight);
00431
00432
00433 for (x = 0, x2 = 0; x < MaxSize; ++x, x2 = x << 1)
00434 {
00435 for (i = 0; i < FormatSize; ++i)
00436 {
00437
00438 ImageBuffer[ x * FormatSize + i ] = (
00439 OldImageBuffer[ ( x2 ) * FormatSize + i ] +
00440 OldImageBuffer[ ( x2 + 1 ) * FormatSize + i ]
00441 ) / 2;
00442 }
00443 }
00444
00445 }
00446
00447
00448 delete [] OldImageBuffer;
00449 }
00450
00451 template <typename T, s32 DefVal> void convertImageFormat(T* &ImageBuffer, s32 Width, s32 Height, s32 OldFormatSize, s32 NewFormatSize)
00452 {
00453
00454 if (!ImageBuffer || Width <= 0 || Height <= 0 || OldFormatSize < 1 || OldFormatSize > 4 ||
00455 NewFormatSize < 1 || NewFormatSize > 4 || OldFormatSize == NewFormatSize)
00456 {
00457 #ifdef SP_DEBUGMODE
00458 io::Log::debug("ImageConverter::convertImageFormat");
00459 #endif
00460 return;
00461 }
00462
00463
00464 s32 x, y, i = 0, j = 0;
00465
00466
00467 T* NewImageBuffer = new T[ Width * Height * NewFormatSize ];
00468
00469
00470 for (y = 0; y < Height; ++y)
00471 {
00472 for (x = 0; x < Width; ++x, i += OldFormatSize, j += NewFormatSize)
00473 {
00474
00475
00476 switch (OldFormatSize)
00477 {
00478 case 1:
00479 switch (NewFormatSize)
00480 {
00481 case 2: __SP_CONVERT_1_TO_2(ImageBuffer, NewImageBuffer, i, j); break;
00482 case 3: __SP_CONVERT_1_TO_3(ImageBuffer, NewImageBuffer, i, j); break;
00483 case 4: __SP_CONVERT_1_TO_4(ImageBuffer, NewImageBuffer, i, j); break;
00484 }
00485 break;
00486
00487 case 2:
00488 switch (NewFormatSize)
00489 {
00490 case 1: __SP_CONVERT_2_TO_1(ImageBuffer, NewImageBuffer, i, j); break;
00491 case 3: __SP_CONVERT_2_TO_3(ImageBuffer, NewImageBuffer, i, j); break;
00492 case 4: __SP_CONVERT_2_TO_4(ImageBuffer, NewImageBuffer, i, j); break;
00493 }
00494 break;
00495
00496 case 3:
00497 switch (NewFormatSize)
00498 {
00499 case 1: __SP_CONVERT_3_TO_1(ImageBuffer, NewImageBuffer, i, j); break;
00500 case 2: __SP_CONVERT_3_TO_2(ImageBuffer, NewImageBuffer, i, j); break;
00501 case 4: __SP_CONVERT_3_TO_4(ImageBuffer, NewImageBuffer, i, j); break;
00502 }
00503 break;
00504
00505 case 4:
00506 switch (NewFormatSize)
00507 {
00508 case 1: __SP_CONVERT_4_TO_1(ImageBuffer, NewImageBuffer, i, j); break;
00509 case 2: __SP_CONVERT_4_TO_2(ImageBuffer, NewImageBuffer, i, j); break;
00510 case 3: __SP_CONVERT_4_TO_3(ImageBuffer, NewImageBuffer, i, j); break;
00511 }
00512 break;
00513 }
00514
00515 }
00516 }
00517
00518
00519 delete [] ImageBuffer;
00520
00521
00522 ImageBuffer = NewImageBuffer;
00523 }
00524
00525 template <typename T> void blurImage(T* &ImageBuffer, s32 Width, s32 Height, s32 FormatSize)
00526 {
00527
00528 if (!ImageBuffer || Width <= 0 || Height <= 0 || FormatSize < 1 || FormatSize > 4)
00529 {
00530 #ifdef SP_DEBUGMODE
00531 io::Log::debug("ImageConverter::blurImage");
00532 #endif
00533 return;
00534 }
00535
00536
00537 s32 y, x, i;
00538
00539
00540 T* NewImageBuffer = new T[ Width * Height * FormatSize ];
00541
00542
00543 for (y = 0; y < Height - 1; ++y)
00544 {
00545 for (x = 0; x < Width - 1; ++x)
00546 {
00547 for (i = 0; i < FormatSize; ++i)
00548 {
00549
00550 NewImageBuffer[ ( y * Width + x ) * FormatSize + i ] = (
00551 ImageBuffer[ ( y * Width + x ) * FormatSize + i ] +
00552 ImageBuffer[ ( y * Width + x+1 ) * FormatSize + i ] +
00553 ImageBuffer[ ( (y+1) * Width + x+1 ) * FormatSize + i ] +
00554 ImageBuffer[ ( (y+1) * Width + x ) * FormatSize + i ]
00555 ) / 4;
00556 }
00557 }
00558 }
00559
00560
00561 for (x = 0; x < Width - 1; ++x)
00562 {
00563 for (i = 0; i < FormatSize; ++i)
00564 {
00565
00566 NewImageBuffer[ ( (Height-1) * Width + x ) * FormatSize + i ] = (
00567 ImageBuffer[ ( (Height-1) * Width + x ) * FormatSize + i ] +
00568 ImageBuffer[ ( (Height-1) * Width + x+1 ) * FormatSize + i ] +
00569 ImageBuffer[ ( x+1 ) * FormatSize + i ] +
00570 ImageBuffer[ ( x ) * FormatSize + i ]
00571 ) / 4;
00572 }
00573 }
00574
00575
00576 for (y = 0; y < Height - 1; ++y)
00577 {
00578 for (i = 0; i < FormatSize; ++i)
00579 {
00580
00581 NewImageBuffer[ ( y * Width + (Width-1) ) * FormatSize + i ] = (
00582 ImageBuffer[ ( y * Width + (Width-1) ) * FormatSize + i ] +
00583 ImageBuffer[ ( y * Width ) * FormatSize + i ] +
00584 ImageBuffer[ ( (y+1) * Width + (Width-1) ) * FormatSize + i ] +
00585 ImageBuffer[ ( (y+1) * Width ) * FormatSize + i ]
00586 ) / 4;
00587 }
00588 }
00589
00590
00591 for (i = 0; i < FormatSize; ++i)
00592 {
00593
00594 NewImageBuffer[ ( (Height-1) * Width + (Width-1) ) * FormatSize + i ] = (
00595 ImageBuffer[ ( (Height-1) * Width + (Width-1) ) * FormatSize + i ] +
00596 ImageBuffer[ ( (Height-1) * Width ) * FormatSize + i ] +
00597 ImageBuffer[ i ] +
00598 ImageBuffer[ ( Width-1 ) * FormatSize + i ]
00599 ) / 4;
00600 }
00601
00602
00603 delete [] ImageBuffer;
00604
00605
00606 ImageBuffer = NewImageBuffer;
00607 }
00608
00609 template <typename T> void turnImage(T* ImageBuffer, s32 Width, s32 Height, s32 FormatSize, const EImageTurnDegrees Degree)
00610 {
00611 if (!ImageBuffer || Width <= 0 || Height <= 0 || FormatSize < 1 || FormatSize > 4)
00612 {
00613 #ifdef SP_DEBUGMODE
00614 io::Log::debug("ImageConverter::turnImage");
00615 #endif
00616 return;
00617 }
00618
00619
00620 s32 x, y, i, j = 0, k;
00621
00622
00623 const u32 ImageBufferSize = Width * Height * FormatSize;
00624
00625
00626 T* TmpImageBuffer = new T[ImageBufferSize];
00627
00628
00629 memcpy(TmpImageBuffer, ImageBuffer, ImageBufferSize);
00630
00631
00632 switch (Degree)
00633 {
00634 case TURNDEGREE_90:
00635 {
00636 for (y = 0; y < Height; ++y)
00637 {
00638 for (x = 0, i = Width*(Height - 1) + y; x < Width; ++x, i -= Width, ++j)
00639 {
00640 for (k = 0; k < FormatSize; ++k)
00641 ImageBuffer[i*FormatSize + k] = TmpImageBuffer[j*FormatSize + k];
00642 }
00643 }
00644 }
00645 break;
00646
00647 case TURNDEGREE_180:
00648 {
00649 for (j = 0, i = Width*Height - 1; j < Width*Height; --i, ++j)
00650 {
00651 for (k = 0; k < FormatSize; ++k)
00652 ImageBuffer[i*FormatSize + k] = TmpImageBuffer[j*FormatSize + k];
00653 }
00654 }
00655 break;
00656
00657 case TURNDEGREE_270:
00658 {
00659 for (y = 0; y < Height; ++y)
00660 {
00661 for (x = 0, i = Width - 1 - y; x < Width; ++x, i += Width, ++j)
00662 {
00663 for (k = 0; k < FormatSize; ++k)
00664 ImageBuffer[i*FormatSize + k] = TmpImageBuffer[j*FormatSize + k];
00665 }
00666 }
00667 }
00668 break;
00669 }
00670
00671
00672 delete [] TmpImageBuffer;
00673 }
00674
00684 template <typename T> void copySubBufferToBuffer(
00685 T* DestBuffer, const T* SrcBuffer, const dim::size2di &DestSize, u32 FormatSize, const dim::point2di &Pos, const dim::size2di &Size)
00686 {
00687
00688 if ( !DestBuffer || !SrcBuffer || FormatSize < 1 || FormatSize > 4 ||
00689 DestSize.Width <= 0 || DestSize.Height <= 0 ||
00690 Pos.X < 0 || Pos.Y < 0 || Size.Width <= 0 || Size.Height <= 0 ||
00691 Pos.X + Size.Width > DestSize.Width || Pos.Y + Size.Height > DestSize.Height )
00692 {
00693 #ifdef SP_DEBUGMODE
00694 io::Log::debug("ImageConverter::copySubBufferToBuffer");
00695 #endif
00696 return;
00697 }
00698
00699
00700 const u32 PixelSize = sizeof(T) * FormatSize;
00701
00702 DestBuffer += (Pos.Y * DestSize.Width + Pos.X) * FormatSize;
00703
00704 if (Size == dim::size2di(1))
00705 memcpy(DestBuffer, SrcBuffer, PixelSize);
00706 else if (DestSize.Width == Size.Width)
00707 memcpy(DestBuffer, SrcBuffer, PixelSize * Size.getArea());
00708 else
00709 {
00710 const u32 SrcLineSize = FormatSize * Size.Width;
00711 const u32 DestLineSize = FormatSize * DestSize.Width;
00712
00713
00714 for (s32 y = Pos.Y; y < Pos.Y + Size.Height; ++y)
00715 {
00716 memcpy(DestBuffer, SrcBuffer, SrcLineSize);
00717
00718 DestBuffer += DestLineSize;
00719 SrcBuffer += SrcLineSize;
00720 }
00721 }
00722 }
00723
00724 template <typename T> void copyBufferToSubBuffer(
00725 T* DestBuffer, const T* SrcBuffer, const dim::size2di &SrcSize, u32 FormatSize, const dim::point2di &Pos, const dim::size2di &Size)
00726 {
00727
00728 if ( !DestBuffer || !SrcBuffer || FormatSize < 1 || FormatSize > 4 ||
00729 SrcSize.Width <= 0 || SrcSize.Height <= 0 ||
00730 Pos.X < 0 || Pos.Y < 0 || Size.Width <= 0 || Size.Height <= 0 ||
00731 Pos.X + Size.Width > SrcSize.Width || Pos.Y + Size.Height > SrcSize.Height )
00732 {
00733 #ifdef SP_DEBUGMODE
00734 io::Log::debug("ImageConverter::copyBufferToSubBuffer");
00735 #endif
00736 return;
00737 }
00738
00739
00740 const u32 PixelSize = sizeof(T) * FormatSize;
00741
00742 SrcBuffer += (Pos.Y * SrcSize.Width + Pos.X) * FormatSize;
00743
00744 if (Size == dim::size2di(1))
00745 memcpy(DestBuffer, SrcBuffer, PixelSize);
00746 else if (SrcSize.Width == Size.Width)
00747 memcpy(DestBuffer, SrcBuffer, PixelSize * Size.getArea());
00748 else
00749 {
00750 const u32 SrcLineSize = FormatSize * SrcSize.Width;
00751 const u32 DestLineSize = FormatSize * Size.Width;
00752
00753 for (s32 y = Pos.Y; y < Pos.Y + Size.Height; ++y)
00754 {
00755 memcpy(DestBuffer, SrcBuffer, SrcLineSize);
00756
00757 DestBuffer += DestLineSize;
00758 SrcBuffer += SrcLineSize;
00759 }
00760 }
00761 }
00762
00763 template <typename T> bool appendImageBufferBottom(
00764 T* &ImageBuffer, const T* AdditionalBuffer, s32 Width, s32 Height, s32 FrameWidth, s32 FrameHeight, s32 FormatSize)
00765 {
00766 if (!ImageBuffer || !AdditionalBuffer || Width <= 0 || Height <= 0 || FormatSize < 1 || FormatSize > 4 || FrameWidth <= 0 || FrameHeight <= 0)
00767 {
00768 #ifdef SP_DEBUGMODE
00769 io::Log::debug("ImageConverter::appendImageBufferBottom");
00770 #endif
00771 return false;
00772 }
00773
00774
00775 T* SizedAddBuf = 0;
00776
00777 u32 AddImageBufferSize = FrameWidth * FrameHeight * FormatSize;
00778
00779 if (FrameWidth != Width)
00780 {
00781
00782 AddImageBufferSize = Width * FrameHeight * FormatSize;
00783 SizedAddBuf = new T[AddImageBufferSize];
00784
00785 scaleImage(AdditionalBuffer, FrameWidth, FrameHeight, SizedAddBuf, Width, FrameHeight, FormatSize);
00786
00787 AdditionalBuffer = SizedAddBuf;
00788 }
00789
00790
00791 const s32 NewHeight = Height + FrameHeight;
00792
00793 const u32 ImageBufferSize = Width * Height * FormatSize;
00794 const u32 NewImageBufferSize = Width * NewHeight * FormatSize;
00795
00796 T* NewImageBuffer = new T[NewImageBufferSize];
00797
00798
00799 memcpy(NewImageBuffer, ImageBuffer, ImageBufferSize * sizeof(T));
00800 memcpy(NewImageBuffer + ImageBufferSize, AdditionalBuffer, AddImageBufferSize * sizeof(T));
00801
00802
00803 delete [] ImageBuffer;
00804 ImageBuffer = NewImageBuffer;
00805
00806
00807 delete [] SizedAddBuf;
00808
00809 return true;
00810 }
00811
00812 template <typename T> bool appendImageBufferRight(
00813 T* &ImageBuffer, const T* AdditionalBuffer, s32 Width, s32 Height, s32 FrameWidth, s32 FrameHeight, s32 FormatSize)
00814 {
00815 #ifdef SP_DEBUGMODE
00816 io::Log::debug("ImageConverter::appendImageBufferRight", "Not implemented yet");
00817 #endif
00818 return false;
00819 }
00820
00821 template <typename T, s32 DefVal> void convertImageGrayToAlpha(T* ImageBuffer, s32 Width, s32 Height)
00822 {
00823 if (!ImageBuffer || Width <= 0 || Height <= 0)
00824 {
00825 #ifdef SP_DEBUGMODE
00826 io::Log::debug("ImageConverter::convertImageGrayToAlpha");
00827 #endif
00828 return;
00829 }
00830
00831
00832 const u32 ImageBufferSize = Width * Height * 4;
00833
00834 for (u32 i = 0; i < ImageBufferSize; i += 4)
00835 {
00836 ImageBuffer[i+3] = ImageBuffer[i];
00837 ImageBuffer[i+0] = DefVal;
00838 ImageBuffer[i+1] = DefVal;
00839 ImageBuffer[i+2] = DefVal;
00840 }
00841 }
00842
00843 }
00844
00845
00846
00847
00848
00849
00850 #undef __SP_CONVERT_1_TO_2
00851 #undef __SP_CONVERT_1_TO_3
00852 #undef __SP_CONVERT_1_TO_4
00853
00854 #undef __SP_CONVERT_2_TO_1
00855 #undef __SP_CONVERT_2_TO_3
00856 #undef __SP_CONVERT_2_TO_4
00857
00858 #undef __SP_CONVERT_3_TO_1
00859 #undef __SP_CONVERT_3_TO_2
00860 #undef __SP_CONVERT_3_TO_4
00861
00862 #undef __SP_CONVERT_4_TO_1
00863 #undef __SP_CONVERT_4_TO_2
00864 #undef __SP_CONVERT_4_TO_3
00865
00866
00867 }
00868
00869 }
00870
00871
00872 #endif
00873
00874
00875
00876