tiff.c
上传用户:wstnjxml
上传日期:2014-04-03
资源大小:7248k
文件大小:13k
源码类别:

Windows CE

开发平台:

C/C++

  1. /*****************************************************************************
  2.  *
  3.  * This program is free software ; you can redistribute it and/or modify
  4.  * it under the terms of the GNU General Public License as published by
  5.  * the Free Software Foundation; either version 2 of the License, or
  6.  * (at your option) any later version.
  7.  *
  8.  * This program is distributed in the hope that it will be useful,
  9.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11.  * GNU General Public License for more details.
  12.  *
  13.  * You should have received a copy of the GNU General Public License
  14.  * along with this program; if not, write to the Free Software
  15.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  16.  *
  17.  * $Id: tiff.c 313 2005-10-29 15:15:47Z picard $
  18.  *
  19.  * The Core Pocket Media Player
  20.  * Copyright (c) 2004-2005 Gabor Kovacs
  21.  *
  22.  ****************************************************************************/
  23.  
  24. #include "../common/common.h"
  25. #include "../common/zlib/zlib.h"
  26. #include "tiff.h"
  27. DECLARE_BITINIT
  28. DECLARE_BITLOAD
  29. typedef struct tiff
  30. {
  31. codec Codec;
  32. buffer Buffer;
  33. bool_t ErrorShowed;
  34. bool_t BigEndian;
  35. const uint8_t* Ptr;
  36. int BitCount;
  37. int BytesPerRow;
  38. int BytesPerRow2;
  39. int Planar;
  40. int Channels;
  41. int Left;
  42. bool_t Reverse;
  43. } tiff;
  44. static int UpdateInput(tiff* p)
  45. {
  46. p->ErrorShowed = 0;
  47. BufferClear(&p->Buffer);
  48. if (p->Codec.In.Format.Type == PACKET_VIDEO)
  49. {
  50. PacketFormatCopy(&p->Codec.Out.Format,&p->Codec.In.Format);
  51. p->Codec.Out.Format.Format.Video.Pixel.Flags = PF_RGB;
  52. p->Codec.Out.Format.Format.Video.Pixel.BitCount = 24;
  53. p->Codec.Out.Format.Format.Video.Pixel.BitMask[0] = 0xFF;
  54. p->Codec.Out.Format.Format.Video.Pixel.BitMask[1] = 0xFF00;
  55. p->Codec.Out.Format.Format.Video.Pixel.BitMask[2] = 0xFF0000;
  56. DefaultPitch(&p->Codec.Out.Format.Format.Video);
  57. }
  58. return ERR_NONE;
  59. }
  60. static NOINLINE int Read32(tiff* p)
  61. {
  62. int v;
  63. if (p->BigEndian)
  64. v = LOAD32BE(p->Ptr);
  65. else
  66. v = LOAD32LE(p->Ptr);
  67. p->Ptr += 4;
  68. return v;
  69. }
  70. static NOINLINE int Read16(tiff* p)
  71. {
  72. int v;
  73. if (p->BigEndian)
  74. v = LOAD16BE(p->Ptr);
  75. else
  76. v = LOAD16LE(p->Ptr);
  77. p->Ptr += 2;
  78. return v;
  79. }
  80. static NOINLINE int ReadVal(tiff* p,int Type)
  81. {
  82. switch (Type)
  83. {
  84. case 1: return *(p->Ptr++);
  85. case 3: return Read16(p);
  86. case 4: return Read32(p);
  87. }
  88. return 0;
  89. }
  90. static NOINLINE int NotSupported(tiff* p)
  91. {
  92. if (!p->ErrorShowed)
  93. {
  94. p->ErrorShowed = 1;
  95. ShowError(p->Codec.Node.Class,TIFF_ID,TIFF_NOT_SUPPORTED);
  96. }
  97. return ERR_NOT_SUPPORTED;
  98. }
  99. static NOINLINE void Write(tiff* p,const uint8_t* Data,int Size)
  100. {
  101. int n,i,j;
  102. if (p->Planar == 1)
  103. {
  104. while (Size>0)
  105. {
  106. if (!p->Left)
  107. p->Left = p->BytesPerRow;
  108. n = min(p->Left,Size);
  109. Size -= n;
  110. p->Left -= n;
  111. switch (p->BitCount)
  112. {
  113. case 1:
  114. j = n*8;
  115. if (!p->Left)
  116. j -= 8*p->BytesPerRow - p->BytesPerRow2;
  117. for (i=0;i<j;++i)
  118. p->Buffer.Data[p->Buffer.WritePos++] = (uint8_t)((Data[i>>3] >> (7-(i&7))) & 1);
  119. break;
  120. case 2:
  121. j = n*4;
  122. if (!p->Left)
  123. j -= 4*p->BytesPerRow - p->BytesPerRow2;
  124. for (i=0;i<j;++i)
  125. p->Buffer.Data[p->Buffer.WritePos++] = (uint8_t)((Data[i>>2] >> (6-2*(i&3))) & 3);
  126. break;
  127. case 4:
  128. j = n*2;
  129. if (!p->Left)
  130. j -= 2*p->BytesPerRow - p->BytesPerRow2;
  131. for (i=0;i<j;++i)
  132. p->Buffer.Data[p->Buffer.WritePos++] = (uint8_t)((Data[i>>1] >> (4-4*(i&1))) & 15);
  133. break;
  134. default:
  135. memcpy(p->Buffer.Data + p->Buffer.WritePos,Data,n);
  136. p->Buffer.WritePos += n;
  137. break;
  138. }
  139. Data += n;
  140. if (!p->Left)
  141. p->Buffer.WritePos += p->Codec.Out.Format.Format.Video.Pitch - p->BytesPerRow2;
  142. }
  143. }
  144. else
  145. {
  146. while (Size>0)
  147. {
  148. if (!p->Left)
  149. p->Left = p->BytesPerRow;
  150. n = min(p->Left,Size);
  151. Size -= n;
  152. p->Left -= n;
  153. while (--n>=0)
  154. {
  155. p->Buffer.Data[p->Buffer.WritePos] = *(++Data);
  156. p->Buffer.WritePos += p->Channels;
  157. }
  158. if (!p->Left)
  159. p->Buffer.WritePos += p->Codec.Out.Format.Format.Video.Pitch - p->BytesPerRow*p->Channels;
  160. }
  161. }
  162. }
  163. static void Inflate(tiff *p,const uint8_t* Data,int Size,int Total)
  164. {
  165. int i,n;
  166. z_stream Inflate;
  167. uint8_t Buffer[4096];
  168. memset(&Inflate,0,sizeof(Inflate));
  169.     if (inflateInit2(&Inflate, MAX_WBITS) == Z_OK)
  170. {
  171. Inflate.next_in = (Bytef*)Data;
  172. Inflate.avail_in = Size;
  173. do
  174. {
  175. Inflate.next_out = Buffer;
  176. Inflate.avail_out = sizeof(Buffer);
  177. i = inflate(&Inflate, Z_SYNC_FLUSH);
  178. n = sizeof(Buffer) - Inflate.avail_out;
  179. if (n>Total)
  180. n=Total;
  181. Write(p,Buffer,n);
  182. Total -= n;
  183. } while (i>=0 && i!=Z_STREAM_END && Total>0);
  184. inflateEnd(&Inflate);
  185. }
  186. }
  187. /*
  188. static void Fax3(tiff *p,const uint8_t* Data,int Size,int Total)
  189. {
  190. //todo
  191. }
  192. */
  193. static void LZW(tiff *p,const uint8_t* Data,int Size)
  194. {
  195. bitstream bs;
  196. uint16_t Prefix[4096];
  197. uint8_t Suffix[4096];
  198. uint8_t Stack[4096];
  199. uint8_t FirstChar;
  200. int ClearCode = 256;
  201. int EOICode = ClearCode+1;
  202. int FreeCode = ClearCode+2;
  203. int OldCode = -1;
  204. int CodeSize = 9;
  205. int i;
  206. for (i=0;i<ClearCode;++i)
  207. Suffix[i] = (uint8_t)i;
  208. FirstChar = 0;
  209. bitinit(&bs,Data,Size);
  210. while (!biteof(&bs))
  211. {
  212. uint8_t* StackPtr;
  213. int Code;
  214. bitload(&bs);
  215. Code = bitget(&bs,CodeSize);
  216. if (Code == EOICode)
  217. break;
  218. if (Code == ClearCode)
  219. {
  220. CodeSize = 9;
  221. FreeCode = ClearCode + 2;
  222. OldCode = -1;
  223. continue;
  224. }
  225. if (Code > FreeCode)
  226. break;
  227. if (OldCode<0)
  228. {
  229. FirstChar = Suffix[Code];
  230. Write(p,&FirstChar,1);
  231. OldCode = Code;
  232. continue;
  233. }
  234. StackPtr = Stack+sizeof(Stack);
  235. i = Code;
  236. if (i == FreeCode)
  237. {
  238. *(--StackPtr) = FirstChar;
  239. i = OldCode;
  240. }
  241. while (i>ClearCode)
  242. {
  243. *(--StackPtr) = Suffix[i];
  244. i = Prefix[i];
  245. }
  246. FirstChar = Suffix[i];
  247. *(--StackPtr) = FirstChar;
  248. Prefix[FreeCode] = (uint16_t)OldCode;
  249. Suffix[FreeCode] = FirstChar;
  250. if (FreeCode < 4096) ++FreeCode;
  251. if (CodeSize<12 && FreeCode == (1<<CodeSize)-1)
  252. ++CodeSize;
  253. OldCode = Code;
  254. Write(p,StackPtr,Stack+sizeof(Stack)-StackPtr);
  255. }
  256. }
  257. static int Process(tiff* p, const packet* Packet, const flowstate* State)
  258. {
  259. int n,Compress;
  260. size_t IFD;
  261. int RowPerStrip;
  262. video Video;
  263. const uint8_t *Strips;
  264. rgb Pal[256];
  265. int StripsType,StripsLen;
  266. int Bits[3];
  267. int BitCount;
  268. int h,ch;
  269. int i,j,k;
  270. if (!Packet)
  271. return ERR_NEED_MORE_DATA;
  272. p->Ptr = Packet->Data[0];
  273. if (Packet->Length<8)
  274. return ERR_INVALID_DATA;
  275. if (p->Ptr[0]=='M' && p->Ptr[1]=='M')
  276. p->BigEndian = 1;
  277. else
  278. if (p->Ptr[0]=='I' && p->Ptr[1]=='I')
  279. p->BigEndian = 0;
  280. else
  281. return ERR_INVALID_DATA;
  282. p->Ptr += 2;
  283. if (Read16(p) != 42)
  284. return ERR_INVALID_DATA;
  285. IFD = Read32(p);
  286. if (IFD<8 || IFD+2+4 >= Packet->Length)
  287. return ERR_INVALID_DATA;
  288. p->Reverse = 0;
  289. RowPerStrip = MAX_INT;
  290. memset(&Video,0,sizeof(Video));
  291. p->Planar = 1;
  292. p->Channels = 0;
  293. Compress = 1;
  294. Strips = NULL;
  295. StripsType = 0;
  296. StripsLen = 0;
  297. BitCount = 0;
  298. Video.Pixel.Flags = PF_RGB;
  299. Video.Aspect = ASPECT_ONE; //todo
  300. for (i=0;i<256;++i)
  301. Pal[i].v = CRGB(i,i,i);
  302. p->Ptr = (const uint8_t*)Packet->Data[0]+IFD;
  303. n = Read16(p);
  304. while (--n>=0)
  305. {
  306. const uint8_t* Save = p->Ptr+12;
  307. int Tag = Read16(p);
  308. int Type = Read16(p);
  309. int Len = Read32(p);
  310. size_t Pos = Read32(p);
  311. switch (Type)
  312. {
  313. case 1: 
  314. case 2: i=1; break;
  315. case 3: i=2; break;
  316. case 4: i=4; break;
  317. case 5: i=8; break;
  318. default: i=0; break;
  319. }
  320. i *= Len;
  321. if (i<=4)
  322. p->Ptr -= 4;
  323. else
  324. {
  325. if (Pos > Packet->Length-i)
  326. continue;
  327. p->Ptr = (const uint8_t*)Packet->Data[0]+Pos;
  328. }
  329. // read integer
  330. i = 0;
  331. if (Len==1) 
  332. switch (Type)
  333. {
  334. case 1: i=p->Ptr[0]; break;
  335. case 3: i=Read16(p); p->Ptr-=2; break;
  336. case 4: i=Read32(p); p->Ptr-=4; break;
  337. }
  338. switch (Tag)
  339. {
  340. case 0x100:
  341. Video.Width = i;
  342. break;
  343. case 0x101:
  344. Video.Height = i;
  345. break;
  346. case 0x102: 
  347. if (Len>3)
  348. return NotSupported(p);
  349. p->Channels = Len;
  350. BitCount = 0;
  351. for (i=0;i<Len;++i)
  352. {
  353. Bits[i] = ReadVal(p,Type);
  354. Video.Pixel.BitMask[i] = ((1 << Bits[i])-1) << BitCount;
  355. BitCount += Bits[i];
  356. }
  357. p->BitCount = BitCount;
  358. Video.Pixel.BitCount = BitCount;
  359. if (Video.Pixel.BitCount==1 ||
  360. Video.Pixel.BitCount==2 ||
  361. Video.Pixel.BitCount==4)
  362. {
  363. int n = 1<<BitCount;
  364. for (i=0;i<n;++i)
  365. {
  366. int j = (255*i)/(n-1);
  367. Pal[i].v = CRGB(j,j,j);
  368. }
  369. Video.Pixel.BitCount=8;
  370. }
  371. if (Video.Pixel.BitCount & 7) // only 1,2,4,8,16,24,32 bitdepth supported
  372. return NotSupported(p);
  373. break;
  374. case 0x103:
  375. Compress = i;
  376. break;
  377. case 0x106:
  378. switch (i)
  379. {
  380. case 0: // invert grayscale
  381. Video.Pixel.Flags = PF_GRAYSCALE|PF_PALETTE;
  382. for (i=0;i<256;++i)
  383. Pal[i].v ^= CRGB(255,255,255);
  384. break;
  385. case 1: // grayscale
  386. Video.Pixel.Flags = PF_GRAYSCALE|PF_PALETTE;
  387. break;
  388. case 2: // rgb
  389. Video.Pixel.Flags = PF_RGB;
  390. break;
  391. case 3: // palette
  392. Video.Pixel.Flags = PF_PALETTE;
  393. break;
  394. }
  395. break;
  396. case 0x10A: // fill order
  397. p->Reverse = i==2;
  398. break;
  399. case 0x111: // strip offsets
  400. Strips = p->Ptr;
  401. StripsType = Type;
  402. StripsLen = Len;
  403. break;
  404. case 0x116: 
  405. RowPerStrip = i; 
  406. break;
  407. case 0x11C:
  408. p->Planar = i;
  409. if (i != 1 && BitCount != p->Channels*8) // only 24,32 supported
  410. return NotSupported(p);
  411. break;
  412. case 0x15B:
  413. // jpeg tables
  414. break;
  415. case 0x140:
  416. Video.Pixel.Flags = PF_PALETTE;
  417. k = 1<<BitCount;
  418. if (Len >= 3*k)
  419. for (j=0;j<3;++j)
  420. for (i=0;i<k;++i)
  421. Pal[i].ch[j] = (uint8_t)(ReadVal(p,Type)>>8);
  422. break;
  423. }
  424. p->Ptr = Save;
  425. }
  426. if (!Strips || !Video.Width || !Video.Height || !p->Channels) 
  427. return ERR_INVALID_DATA; 
  428. if ((Video.Pixel.Flags & PF_PALETTE) && (p->Channels!=1 || Video.Pixel.BitCount!=8))
  429. return NotSupported(p);
  430. DefaultPitch(&Video);
  431. if (!EqVideo(&Video,&p->Codec.Out.Format.Format.Video))
  432. {
  433. if ((Video.Pixel.Flags & PF_PALETTE) && PacketFormatExtra(&p->Codec.Out.Format,sizeof(Pal)))
  434. {
  435. memcpy(p->Codec.Out.Format.Extra,Pal,sizeof(Pal));
  436. Video.Pixel.Palette = p->Codec.Out.Format.Extra;
  437. }
  438. p->Codec.In.Format.Format.Video.Width = Video.Width;
  439. p->Codec.In.Format.Format.Video.Height = Video.Height;
  440. p->Codec.Out.Format.Format.Video = Video;
  441. ConnectionUpdate(&p->Codec.Node,CODEC_OUTPUT,p->Codec.Out.Pin.Node,p->Codec.Out.Pin.No);
  442. }
  443. BufferDrop(&p->Buffer);
  444. if (!BufferAlloc(&p->Buffer,Video.Pitch*Video.Height,4096))
  445. return ERR_OUT_OF_MEMORY;
  446. p->Ptr = Strips;
  447. p->Left = 0;
  448. ch = 0;
  449. h = Video.Height;
  450. for (n=0;n<StripsLen && h>0;++n)
  451. {
  452. int Len,Pos,y;
  453. const uint8_t* Src;
  454. Pos = ReadVal(p,StripsType);
  455. Len = Packet->Length - Pos;
  456. if (Len <= 0)
  457. break;
  458. Src = (const uint8_t*)Packet->Data[0]+Pos;
  459. y = min(RowPerStrip,h);
  460. h -= y;
  461. if (p->Planar == 1)
  462. {
  463. p->BytesPerRow = ((BitCount*Video.Width + 7) >> 3);
  464. p->BytesPerRow2 = ((Video.Pixel.BitCount*Video.Width + 7) >> 3);
  465. }
  466. else
  467. p->BytesPerRow2 = p->BytesPerRow = ((Bits[ch] * Video.Width + 7) >> 3);
  468. switch (Compress)
  469. {
  470. case 1:
  471. Write(p,Src,p->BytesPerRow*y);
  472. break;
  473. // case 2: //rle
  474. // break;
  475. // case 3: //fax3
  476. // Fax3(p,Src,Len,p->BytesPerRow*y);
  477. // break;
  478. // case 4: //fax4
  479. // break;
  480. case 5:
  481. LZW(p,Src,Len);
  482. break; 
  483. case 8:
  484. case 32946: //zlib
  485. Inflate(p,Src,Len,p->BytesPerRow*y);
  486. break;
  487. default:
  488. return NotSupported(p);
  489. }
  490. if (p->Planar != 1 && h==0)
  491. {
  492. // next plane
  493. if (ch == p->Channels) break;
  494. h = Video.Height;
  495. p->Left = 0;
  496. p->Buffer.WritePos = ++ch;
  497. }
  498. }
  499. p->Codec.Packet.RefTime = Packet->RefTime;
  500. p->Codec.Packet.Length = p->Buffer.WritePos;
  501. p->Codec.Packet.Data[0] = p->Buffer.Data;
  502. return ERR_NONE;
  503. }
  504. static int Resend(tiff* p)
  505. {
  506. int Result = ERR_INVALID_DATA;
  507. if (p->Buffer.WritePos)
  508. {
  509. packet Packet;
  510. flowstate State;
  511. State.CurrTime = TIME_RESEND;
  512. State.DropLevel = 0;
  513. memset(&Packet,0,sizeof(Packet));
  514. Packet.RefTime = TIME_UNKNOWN;
  515. Packet.Length = p->Buffer.WritePos;
  516. Packet.Data[0] = p->Buffer.Data;
  517. Result = p->Codec.Out.Process(p->Codec.Out.Pin.Node,&Packet,&State);
  518. }
  519. return Result;
  520. }
  521. static int Flush(tiff* p)
  522. {
  523. BufferDrop(&p->Buffer);
  524. return ERR_NONE;
  525. }
  526. static int Create(tiff* p)
  527. {
  528. p->Codec.Process = (packetprocess)Process;
  529. p->Codec.UpdateInput = (nodefunc)UpdateInput;
  530. p->Codec.ReSend = (nodefunc)Resend;
  531. p->Codec.Flush = (nodefunc)Flush;
  532. return ERR_NONE;
  533. }
  534. static const nodedef TIFF =
  535. {
  536. sizeof(tiff),
  537. TIFF_ID,
  538. CODEC_CLASS,
  539. PRI_DEFAULT,
  540. (nodecreate)Create,
  541. NULL,
  542. };
  543. //-------------------------------------------------------------------------------------------
  544. static const nodedef TIFFFile =
  545. {
  546. 0, // parent size
  547. TIFF_FILE_ID,
  548. RAWIMAGE_CLASS,
  549. PRI_DEFAULT,
  550. };
  551. //---------------------------------------------------------------------------------------------
  552. void TIFF_Init()
  553. {
  554. NodeRegisterClass(&TIFF);
  555. NodeRegisterClass(&TIFFFile);
  556. }
  557. void TIFF_Done()
  558. {
  559. NodeUnRegisterClass(TIFF_ID);
  560. NodeUnRegisterClass(TIFF_FILE_ID);
  561. }