il_pcd.c
Upload User: wmy0603
Upload Date: 2022-05-02
Package Size: 1808k
Code Size: 4k
Development Platform:

Visual C++

  1. //-----------------------------------------------------------------------------
  2. //
  3. // ImageLib Sources
  4. // Copyright (C) 2000-2009 by Denton Woods
  5. // Last modified: 03/07/2009
  6. //
  7. // Filename: src-IL/src/il_pcd.c
  8. //
  9. // Description: Reads from a Kodak PhotoCD (.pcd) file.
  10. // Note:  The code here is sloppy - I had to convert it from Pascal,
  11. // which I've never even attempted to read before...enjoy! =)
  12. //
  13. //-----------------------------------------------------------------------------
  14. #include "il_internal.h"
  15. #ifndef IL_NO_PCD
  16. #include "il_manip.h"
  17. ILboolean iLoadPcdInternal(void);
  18. //! Reads a .pcd file
  19. ILboolean ilLoad_PCD(ILconst_string FileName)
  20. {
  21. ILHANDLE PcdFile;
  22. ILboolean bPcd = IL_FALSE;
  23. PcdFile = iopenr(FileName);
  24. if (PcdFile == NULL) {
  25. ilSetError(IL_COULD_NOT_OPEN_FILE);
  26. return bPcd;
  27. }
  28. bPcd = ilLoadF_PCD(PcdFile);
  29. icloser(PcdFile);
  30. return bPcd;
  31. }
  32. //! Reads an already-opened .pcd file
  33. ILboolean ilLoadF_PCD(ILHANDLE File)
  34. {
  35. ILuint FirstPos;
  36. ILboolean bRet;
  37. iSetInputFile(File);
  38. FirstPos = itell();
  39. bRet = iLoadPcdInternal();
  40. iseek(FirstPos, IL_SEEK_SET);
  41. return bRet;
  42. }
  43. //! Reads from a memory "lump" that contains a .pcd file
  44. ILboolean ilLoadL_PCD(const void *Lump, ILuint Size)
  45. {
  46. iSetInputLump(Lump, Size);
  47. return iLoadPcdInternal();
  48. }
  49. void YCbCr2RGB(ILubyte Y, ILubyte Cb, ILubyte Cr, ILubyte *r, ILubyte *g, ILubyte *b)
  50. {
  51. static const ILdouble c11 = 0.0054980*256;
  52. static const ILdouble c12 = 0.0000000*256;
  53. static const ILdouble c13 = 0.0051681*256;
  54. static const ILdouble c21 = 0.0054980*256;
  55. static const ILdouble c22 =-0.0015446*256;
  56. static const ILdouble c23 =-0.0026325*256;
  57. static const ILdouble c31 = 0.0054980*256;
  58. static const ILdouble c32 = 0.0079533*256;
  59. static const ILdouble c33 = 0.0000000*256;
  60. ILint r1, g1, b1;
  61. r1 = (ILint)(c11*Y + c12*(Cb-156) + c13*(Cr-137));
  62. g1 = (ILint)(c21*Y + c22*(Cb-156) + c23*(Cr-137));
  63. b1 = (ILint)(c31*Y + c32*(Cb-156) + c33*(Cr-137));
  64. if (r1 < 0)
  65. *r = 0;
  66. else if (r1 > 255)
  67. *r = 255;
  68. else
  69. *r = r1;
  70. if (g1 < 0)
  71. *g = 0;
  72. else if (g1 > 255)
  73. *g = 255;
  74. else
  75. *g = g1;
  76. if (b1 < 0)
  77. *b = 0;
  78. else if (b1 > 255)
  79. *b = 255;
  80. else
  81. *b = b1;
  82. return;
  83. }
  84. ILboolean iLoadPcdInternal()
  85. {
  86. ILubyte VertOrientation;
  87. ILuint Width, Height, i, Total, x, CurPos = 0;
  88. ILubyte *Y1=NULL, *Y2=NULL, *CbCr=NULL, r = 0, g = 0, b = 0;
  89. ILuint PicNum;
  90. if (iCurImage == NULL) {
  91. ilSetError(IL_ILLEGAL_OPERATION);
  92. return IL_FALSE;
  93. }
  94. iseek(72, IL_SEEK_CUR);
  95. if (iread(&VertOrientation, 1, 1) != 1)
  96. return IL_FALSE;
  97. iseek(-72, IL_SEEK_CUR);  // Can't rewind
  98. PicNum = iGetInt(IL_PCD_PICNUM);
  99. switch (PicNum)
  100. {
  101. case 0:
  102. iseek(0x02000, IL_SEEK_CUR);
  103. Width = 192;
  104. Height = 128;
  105. break;
  106. case 1:
  107. iseek(0x0b800, IL_SEEK_CUR);
  108. Width = 384;
  109. Height = 256;
  110. break;
  111. case 2:
  112. iseek(0x30000, IL_SEEK_CUR);
  113. Width = 768;
  114. Height = 512;
  115. break;
  116. default:
  117. ilSetError(IL_INVALID_PARAM);
  118. return IL_FALSE;
  119. }
  120. if (itell() == IL_EOF)  // Supposed to have data here.
  121. return IL_FALSE;
  122. Y1 = (ILubyte*)ialloc(Width);
  123. Y2 = (ILubyte*)ialloc(Width);
  124. CbCr = (ILubyte*)ialloc(Width);
  125. if (Y1 == NULL || Y2 == NULL || CbCr == NULL) {
  126. ifree(Y1);
  127. ifree(Y2);
  128. ifree(CbCr);
  129. return IL_FALSE;
  130. }
  131. if (!ilTexImage(Width, Height, 1, 3, IL_RGB, IL_UNSIGNED_BYTE, NULL)) {
  132. return IL_FALSE;
  133. }
  134. iCurImage->Origin = IL_ORIGIN_LOWER_LEFT;
  135. Total = Height >> 1;
  136. for (i = 0; i < Total; i++) {
  137. iread(Y1, 1, Width);
  138. iread(Y2, 1, Width);
  139. if (iread(CbCr, 1, Width) != Width) {  // Only really need to check the last one.
  140. ifree(Y1);
  141. ifree(Y2);
  142. ifree(CbCr);
  143. return IL_FALSE;
  144. }
  145. for (x = 0; x < Width; x++) {
  146. YCbCr2RGB(Y1[x], CbCr[x / 2], CbCr[(Width / 2) + (x / 2)], &r, &g, &b);
  147. iCurImage->Data[CurPos++] = r;
  148. iCurImage->Data[CurPos++] = g;
  149. iCurImage->Data[CurPos++] = b;
  150. }
  151. for (x = 0; x < Width; x++) {
  152. YCbCr2RGB(Y2[x], CbCr[x / 2], CbCr[(Width / 2) + (x / 2)], &r, &g, &b);
  153. iCurImage->Data[CurPos++] = r;
  154. iCurImage->Data[CurPos++] = g;
  155. iCurImage->Data[CurPos++] = b;
  156. }
  157. }
  158. ifree(Y1);
  159. ifree(Y2);
  160. ifree(CbCr);
  161. // Not sure how it is...the documentation is hard to understand
  162. if ((VertOrientation & 0x3F) != 8)
  163. iCurImage->Origin = IL_ORIGIN_LOWER_LEFT;
  164. else
  165. iCurImage->Origin = IL_ORIGIN_UPPER_LEFT;
  166. return ilFixImage();
  167. }
  168. #endif//IL_NO_PCD