PSD.cpp 38 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028
  1. /******************************************************************************/
  2. #include "stdafx.h"
  3. namespace EE{
  4. /******************************************************************************/
  5. #if SUPPORT_PSD
  6. struct PSD
  7. {
  8. struct HEADER
  9. {
  10. Byte Signature[4], // always equal 8BPS, do not read file if not
  11. Version [2], // always equal 1, do not read file if not
  12. Reserved [6], // must be zero
  13. Channels [2], // numer of channels including any alpha channels, supported range 1 to 24
  14. Rows [4], // height in PIXELS, supported range 1 to 30000
  15. Columns [4], // width in PIXELS, supported range 1 to 30000
  16. Depth [2], // number of bpp
  17. Mode [2]; // colour mode of the file, Bitmap=0, Grayscale=1, Indexed=2, RGB=3, CMYK=4, Multichannel=7, Duotone=8, Lab=9
  18. };
  19. struct HEADER_INFO
  20. {
  21. //Table 2-12: HeaderInfo Color spaces
  22. // Color-ID Name Description
  23. //-------------------------------------------
  24. // 0 Bitmap // Probably means black & white
  25. // 1 Grayscale The first value in the color data is the gray value, from 0...10000.
  26. // 2 Indexed
  27. // 3 RGB The first three values in the color data are red, green, and blue.
  28. // They are full unsigned 16-bit values as in Apple's RGBColor data
  29. // structure. Pure red=65535,0,0.
  30. // 4 CMYK The four values in the color data are cyan, magenta, yellow, and
  31. // black. They are full unsigned 16-bit values. 0=100% ink. Pure
  32. // cyan=0,65535,65535,65535.
  33. // 7 Multichannel // Have no idea
  34. // 8 Duotone
  35. // 9 Lab The first three values in the color data are lightness, a chrominance,
  36. // and b chrominance.
  37. // Lightness is a 16-bit value from 0...100. The chromanance components
  38. // are each 16-bit values from -128...127. Gray values
  39. // are represented by chrominance components of 0. Pure
  40. // white=100,0,0.
  41. I16 nChannels;
  42. Int nHeight;
  43. Int nWidth;
  44. I16 nBitsPerPixel;
  45. I16 nColourMode;
  46. HEADER_INFO()
  47. {
  48. nChannels=-1;
  49. nHeight=-1;
  50. nWidth=-1;
  51. nBitsPerPixel=-1;
  52. nColourMode=-1;
  53. }
  54. };
  55. struct COLOUR_MODE_DATA
  56. {
  57. Int nLength;
  58. Byte *ColourData;
  59. ~COLOUR_MODE_DATA()
  60. {
  61. DeleteN(ColourData);
  62. }
  63. COLOUR_MODE_DATA()
  64. {
  65. nLength=-1;
  66. ColourData=null;
  67. }
  68. };
  69. struct IMAGE_RESOURCE
  70. {
  71. // Table 2-1: Image resource block
  72. // Type Name Description
  73. //-------------------------------------------
  74. // OSType Type Photoshop always uses its signature, 8BIM
  75. // int16 ID Unique identifier
  76. // PString Name A pascal string, padded to make size even (a null name consists of two bytes of 0)
  77. // Pascal style string where the first byte gives the length of the
  78. // string and the content bytes follow.
  79. // int32 Size Actual size of resource data. This does not include the
  80. // Type, ID, Name, or Size fields.
  81. // Variable Data Resource data, padded to make size even
  82. Int nLength;
  83. char OSType[4];
  84. I16 nID;
  85. Byte *Name;
  86. Int nSize;
  87. IMAGE_RESOURCE()
  88. {
  89. Name=null;
  90. Reset();
  91. }
  92. ~IMAGE_RESOURCE()
  93. {
  94. DeleteN(Name);
  95. }
  96. void Reset()
  97. {
  98. nLength=-1;
  99. REPAO(OSType)=0;
  100. nID=-1;
  101. DeleteN(Name);
  102. nSize=-1;
  103. }
  104. };
  105. struct RESOLUTION_INFO
  106. {
  107. // Table A-6: ResolutionInfo structure
  108. // Type Name Description
  109. //-------------------------------------------
  110. // Fixed hRes Horizontal resolution in pixels per inch.
  111. // Int hResUnit 1=display horizontal resolution in pixels per inch;
  112. // 2=display horizontal resolution in pixels per cm.
  113. // I16 widthUnit Display width as 1=inches; 2=cm; 3=points; 4=picas; 5=columns.
  114. // Fixed vRes Vertical resolution in pixels per inch.
  115. // Int vResUnit 1=display vertical resolution in pixels per inch;
  116. // 2=display vertical resolution in pixels per cm.
  117. // I16 heightUnit Display height as 1=inches; 2=cm; 3=points; 4=picas; 5=columns.
  118. I16 hRes;
  119. Int hResUnit;
  120. I16 widthUnit;
  121. I16 vRes;
  122. Int vResUnit;
  123. I16 heightUnit;
  124. RESOLUTION_INFO()
  125. {
  126. hRes=-1;
  127. hResUnit=-1;
  128. widthUnit=-1;
  129. vRes=-1;
  130. vResUnit=-1;
  131. heightUnit=-1;
  132. }
  133. };
  134. struct RESOLUTION_INFO_v2 // Obsolete - Photoshop 2.0
  135. {
  136. I16 nChannels;
  137. I16 nRows;
  138. I16 nColumns;
  139. I16 nDepth;
  140. I16 nMode;
  141. RESOLUTION_INFO_v2()
  142. {
  143. nChannels=-1;
  144. nRows=-1;
  145. nColumns=-1;
  146. nDepth=-1;
  147. nMode=-1;
  148. }
  149. };
  150. struct DISPLAY_INFO
  151. {
  152. // This structure contains display information about each channel.
  153. //Table A-7: DisplayInfo Color spaces
  154. // Color-ID Name Description
  155. //-------------------------------------------
  156. // 0 RGB The first three values in the color data are red, green, and blue.
  157. // They are full unsigned 16-bit values as in Apple's RGBColor data
  158. // structure. Pure red=65535,0,0.
  159. // 1 HSB The first three values in the color data are hue, saturation, and
  160. // brightness. They are full unsigned 16-bit values as in Apple's
  161. // HSVColor data structure. Pure red=0,65535, 65535.
  162. // 2 CMYK The four values in the color data are cyan, magenta, yellow, and
  163. // black. They are full unsigned 16-bit values. 0=100% ink. Pure
  164. // cyan=0,65535,65535,65535.
  165. // 7 Lab The first three values in the color data are lightness, a chrominance,
  166. // and b chrominance.
  167. // Lightness is a 16-bit value from 0...10000. The chromanance components
  168. // are each 16-bit values from -12800...12700. Gray values
  169. // are represented by chrominance components of 0. Pure
  170. // white=10000,0,0.
  171. // 8 grayscale The first value in the color data is the gray value, from 0...10000.
  172. I16 ColourSpace;
  173. I16 Colour[4];
  174. I16 Opacity; // 0..100
  175. Bool kind; // selected=0, protected=1
  176. Byte padding; // should be zero
  177. DISPLAY_INFO()
  178. {
  179. ColourSpace=-1;
  180. REPAO(Colour)=0;
  181. Opacity=-1;
  182. kind=false;
  183. padding='0';
  184. }
  185. };
  186. struct THUMBNAIL
  187. {
  188. // Adobe Photoshop 5.0 and later stores thumbnail information for preview
  189. // display in an image resource block. These resource blocks consist of an
  190. // 28 byte header, followed by a JFIF thumbnail in RGB (red, green, blue)
  191. // for both Macintosh and Windows. Adobe Photoshop 4.0 stored the
  192. // thumbnail information in the same format except the data section is
  193. // (blue, green, red). The Adobe Photoshop 4.0 format is at resource ID
  194. // and the Adobe Photoshop 5.0 format is at resource ID 1036.
  195. // Table 2-5: Thumnail resource header
  196. // Type Name Description
  197. //-------------------------------------------
  198. // 4 bytes format = 1 (kJpegRGB). Also supports kRawRGB (0).
  199. // 4 bytes width Width of thumbnail in pixels.
  200. // 4 bytes height Height of thumbnail in pixels.
  201. // 4 bytes widthbytes Padded row bytes as (width * bitspixel + 31) / 32 * 4.
  202. // 4 bytes size Total size as widthbytes * height * planes
  203. // 4 bytes compressedsize Size after compression. Used for consistentcy check.
  204. // 2 bytes bitspixel = 24. Bits per pixel.
  205. // 2 bytes planes = 1. Number of planes.
  206. // Variable Data JFIF data in RGB format.
  207. // Note: For resource ID 1033 the data is in BGR format.
  208. Int nFormat;
  209. Int nWidth;
  210. Int nHeight;
  211. Int nWidthBytes;
  212. Int nSize;
  213. Int nCompressedSize;
  214. I16 nBitPerPixel;
  215. I16 nPlanes;
  216. Byte *Data;
  217. THUMBNAIL()
  218. {
  219. nFormat=-1;
  220. nWidth=-1;
  221. nHeight=-1;
  222. nWidthBytes=-1;
  223. nSize=-1;
  224. nCompressedSize=-1;
  225. nBitPerPixel=-1;
  226. nPlanes=-1;
  227. Data=null;
  228. }
  229. };
  230. Bool ReadHeader(File &f, HEADER_INFO& header_info);
  231. Bool ReadColourModeData(File &f, COLOUR_MODE_DATA& colour_mode_data);
  232. Bool ReadImageResource(File &f, IMAGE_RESOURCE& image_resource);
  233. Bool ReadLayerAndMaskInfoSection(File &f);
  234. Bool ReadImageData(File &f, Image &dest);
  235. Bool ProccessBuffer(Byte *pData, Image &dest);
  236. HEADER_INFO header_info;
  237. COLOUR_MODE_DATA colour_mode_data;
  238. I16 mnColourCount;
  239. I16 mnTransparentIndex;
  240. IMAGE_RESOURCE image_resource;
  241. Int mnGlobalAngle;
  242. RESOLUTION_INFO resolution_info;
  243. Bool mbResolutionInfoFilled;
  244. RESOLUTION_INFO_v2 resolution_info_v2;
  245. Bool mbResolutionInfoFilled_v2;
  246. DISPLAY_INFO display_info;
  247. Bool mbDisplayInfoFilled;
  248. THUMBNAIL thumbnail;
  249. Bool mbThumbNailFilled;
  250. Bool mbCopyright;
  251. Bool merged_alpha;
  252. PSD()
  253. {
  254. mbThumbNailFilled=false;
  255. mbDisplayInfoFilled=false;
  256. mbResolutionInfoFilled=false;
  257. mbResolutionInfoFilled_v2=false;
  258. mnGlobalAngle=30;
  259. mbCopyright=false;
  260. mnColourCount=-1;
  261. mnTransparentIndex=-1;
  262. merged_alpha=false;
  263. }
  264. };
  265. /******************************************************************************/
  266. static UInt Calculate(Byte *b, Int digs)
  267. {
  268. UInt v=0; FREP(digs)v=(v<<8)|b[i];
  269. return v;
  270. }
  271. static UInt GetUInt(File &f) {Byte b[4]; f>>b; return Calculate(b, Elms(b));}
  272. static UInt GetU16 (File &f) {Byte b[2]; f>>b; return Calculate(b, Elms(b));}
  273. static Int GetI16 (File &f) {Byte b[2]; f>>b; return (I16)Calculate(b, Elms(b));}
  274. static void XYZToRGB(Dbl x, Dbl y, Dbl z, Int &r, Int &g, Int &b)
  275. {
  276. // Standards used Observer=2, Illuminant=D65
  277. // ref_X=95.047, ref_Y=100.000, ref_Z=108.883
  278. Dbl ref_X= 95.047,
  279. ref_Y=100.000,
  280. ref_Z=108.883;
  281. Dbl var_X=x/100.0,
  282. var_Y=y/100.0,
  283. var_Z=z/100.0;
  284. Dbl var_R=var_X * 3.2406 + var_Y * -1.5372 + var_Z * -0.4986,
  285. var_G=var_X * -0.9689 + var_Y * 1.8758 + var_Z * 0.0415,
  286. var_B=var_X * 0.0557 + var_Y * -0.2040 + var_Z * 1.0570;
  287. if(var_R>0.0031308)var_R=1.055*Pow(var_R, 1/2.4)-0.055;
  288. else var_R=12.92*var_R;
  289. if(var_G>0.0031308)var_G=1.055*Pow(var_G, 1/2.4)-0.055;
  290. else var_G=12.92*var_G;
  291. if(var_B>0.0031308)var_B=1.055*Pow(var_B, 1/2.4)-0.055;
  292. else var_B=12.92*var_B;
  293. r=FltToByte(var_R);
  294. g=FltToByte(var_G);
  295. b=FltToByte(var_B);
  296. }
  297. static void LABToRGB(Dbl L, Dbl A, Dbl B, Int &r, Int &g, Int &b)
  298. {
  299. // For the conversion we first convert values to XYZ and then to RGB
  300. // Standards used Observer=2, Illuminant=D65
  301. // ref_X=95.047, ref_Y=100.000, ref_Z=108.883
  302. Dbl ref_X= 95.047,
  303. ref_Y=100.000,
  304. ref_Z=108.883;
  305. Dbl var_Y=(L + 16.0)/116.0,
  306. var_X= A /500.0 + var_Y,
  307. var_Z=var_Y - B /200.0;
  308. if(Pow(var_Y, 3)>0.008856)var_Y=Pow(var_Y, 3);
  309. else var_Y=(var_Y-16/116)/7.787;
  310. if(Pow(var_X, 3)>0.008856)var_X=Pow(var_X, 3);
  311. else var_X=(var_X-16/116)/7.787;
  312. if(Pow(var_Z, 3)>0.008856)var_Z=Pow(var_Z, 3);
  313. else var_Z=(var_Z-16/116)/7.787;
  314. Dbl x=ref_X*var_X,
  315. y=ref_Y*var_Y,
  316. z=ref_Z*var_Z;
  317. XYZToRGB(x, y, z, r, g, b);
  318. }
  319. static void CMYKToRGB(Dbl c, Dbl m, Dbl y, Dbl k, Int &r, Int &g, Int &b)
  320. {
  321. //r=RoundPos(Sat(1-(c*(1-k)+k))*255.0f);
  322. //g=RoundPos(Sat(1-(m*(1-k)+k))*255.0f);
  323. //b=RoundPos(Sat(1-(y*(1-k)+k))*255.0f);
  324. Dbl colors=1-k;
  325. r=RoundPos(Sat(colors*(1-c))*255);
  326. g=RoundPos(Sat(colors*(1-m))*255);
  327. b=RoundPos(Sat(colors*(1-y))*255);
  328. /*r=RoundPos(Sat(1-Min(1.0, c+k))*255);
  329. g=RoundPos(Sat(1-Min(1.0, m+k))*255);
  330. b=RoundPos(Sat(1-Min(1.0, y+k))*255);*/
  331. /*r=RoundPos(255*Sat(1-Min(1.0, c*(1-k)+k)));
  332. g=RoundPos(255*Sat(1-Min(1.0, m*(1-k)+k)));
  333. b=RoundPos(255*Sat(1-Min(1.0, y*(1-k)+k)));*/
  334. }
  335. /******************************************************************************/
  336. Bool PSD::ReadHeader(File &f, HEADER_INFO& header_info)
  337. {
  338. HEADER header; f>>header;
  339. if(header.Signature[0]=='8' && header.Signature[1]=='B' && header.Signature[2]=='P' && header.Signature[3]=='S')
  340. {
  341. Int ver=Calculate(header.Version, SIZE(header.Version));
  342. if( ver==1)
  343. {
  344. REPA(header.Reserved)if(header.Reserved[i])return false;
  345. header_info.nChannels =Calculate(header.Channels, SIZE(header.Channels));
  346. header_info.nHeight =Calculate(header.Rows , SIZE(header.Rows ));
  347. header_info.nWidth =Calculate(header.Columns , SIZE(header.Columns ));
  348. header_info.nBitsPerPixel=Calculate(header.Depth , SIZE(header.Depth ));
  349. header_info.nColourMode =Calculate(header.Mode , SIZE(header.Mode ));
  350. return f.ok();
  351. }
  352. }
  353. return false;
  354. }
  355. /******************************************************************************/
  356. Bool PSD::ReadColourModeData(File &f, COLOUR_MODE_DATA& colour_mode_data)
  357. {
  358. // Only indexed colour and duotone have colour mode data,
  359. // for all other modes this section is 4 bytes length, the length field is set to zero
  360. // For indexed color images, the length will be equal to 768, and the color
  361. // will contain the color table for the image, in non-interleaved order.
  362. // For duotone images, the color data will contain the duotone specification,
  363. // the format of which is not documented. Other applications that read
  364. // Photoshop files can treat a duotone image as a grayscale image, and just
  365. // preserve the contents of the duotone information when reading and writing
  366. // the file.
  367. // free memory
  368. DeleteN(colour_mode_data.ColourData);
  369. colour_mode_data.nLength=GetUInt(f);
  370. if(colour_mode_data.nLength>0)
  371. {
  372. colour_mode_data.ColourData=new Byte[colour_mode_data.nLength];
  373. f.get(colour_mode_data.ColourData, colour_mode_data.nLength);
  374. }
  375. return f.ok();
  376. }
  377. /******************************************************************************/
  378. Bool PSD::ReadLayerAndMaskInfoSection(File &f)
  379. {
  380. UInt size=GetUInt(f);
  381. Long pos=f.pos()+size;
  382. if(size)
  383. if(UInt layer_len=GetUInt(f))
  384. {
  385. Int layers=GetI16(f);
  386. if( layers<0)
  387. {
  388. merged_alpha=true;
  389. CHS(layers);
  390. }
  391. }
  392. f.pos(pos);
  393. return f.ok();
  394. }
  395. /******************************************************************************/
  396. Bool PSD::ReadImageResource(File &f, IMAGE_RESOURCE& image_resource)
  397. {
  398. image_resource.nLength=GetUInt(f);
  399. #if 1
  400. f.skip(image_resource.nLength);
  401. return f.ok();
  402. #else
  403. Int nBytesRead=0,
  404. nTotalBytes=image_resource.nLength;
  405. for(; !f.end() && nBytesRead<nTotalBytes; )
  406. {
  407. image_resource.Reset();
  408. nBytesRead+=f.getReturnSize(image_resource.OSType, SIZE(image_resource.OSType));
  409. assert(nBytesRead%2==0);
  410. if(image_resource.OSType[0]=='8' && image_resource.OSType[1]=='B' && image_resource.OSType[2]=='I' && image_resource.OSType[3]=='M')
  411. {
  412. Byte ID[2];
  413. nItemsRead=fread(&ID, SIZE(ID), 1, pFile);
  414. nBytesRead += nItemsRead * SIZE(ID);
  415. image_resource.nID=Calculate(ID, SIZE(ID));
  416. Byte SizeOfName;
  417. nItemsRead=fread(&SizeOfName, SIZE(SizeOfName), 1, pFile);
  418. nBytesRead += nItemsRead * SIZE(SizeOfName);
  419. Int nSizeOfName=Calculate(&SizeOfName, SIZE(SizeOfName));
  420. if(0<nSizeOfName)
  421. {
  422. image_resource.Name=new Byte[nSizeOfName];
  423. nItemsRead=fread(image_resource.Name, nSizeOfName, 1, pFile);
  424. nBytesRead += nItemsRead * nSizeOfName;
  425. }
  426. if(0 == (nSizeOfName % 2))
  427. {
  428. nItemsRead=fread(&SizeOfName, SIZE(SizeOfName), 1, pFile);
  429. nBytesRead += nItemsRead * SIZE(SizeOfName);
  430. }
  431. Byte Size[4];
  432. nItemsRead=fread(&Size, SIZE(Size), 1, pFile);
  433. nBytesRead += nItemsRead * SIZE(Size);
  434. image_resource.nSize=Calculate(Size, SIZE(image_resource.nSize));
  435. if(0 != (image_resource.nSize % 2))image_resource.nSize++; // resource data must be even
  436. if(0<image_resource.nSize)
  437. {
  438. Byte IntValue[4];
  439. Byte ShortValue[2];
  440. switch(image_resource.nID)
  441. {
  442. case 1000:
  443. {
  444. // Obsolete - Photoshop 2.0
  445. mbResolutionInfoFilled_v2=true;
  446. nItemsRead=fread(&ShortValue, SIZE(ShortValue), 1, pFile);
  447. nBytesRead += nItemsRead * SIZE(ShortValue);
  448. resolution_info_v2.nChannels=Calculate(ShortValue, SIZE(resolution_info_v2.nChannels));
  449. nItemsRead=fread(&ShortValue, SIZE(ShortValue), 1, pFile);
  450. nBytesRead += nItemsRead * SIZE(ShortValue);
  451. resolution_info_v2.nRows=Calculate(ShortValue, SIZE(resolution_info_v2.nRows));
  452. nItemsRead=fread(&ShortValue, SIZE(ShortValue), 1, pFile);
  453. nBytesRead += nItemsRead * SIZE(ShortValue);
  454. resolution_info_v2.nColumns=Calculate(ShortValue, SIZE(resolution_info_v2.nColumns));
  455. nItemsRead=fread(&ShortValue, SIZE(ShortValue), 1, pFile);
  456. nBytesRead += nItemsRead * SIZE(ShortValue);
  457. resolution_info_v2.nDepth=Calculate(ShortValue, SIZE(resolution_info_v2.nDepth));
  458. nItemsRead=fread(&ShortValue, SIZE(ShortValue), 1, pFile);
  459. nBytesRead += nItemsRead * SIZE(ShortValue);
  460. resolution_info_v2.nMode=Calculate(ShortValue, SIZE(resolution_info_v2.nMode));
  461. }break;
  462. case 1005:
  463. {
  464. mbResolutionInfoFilled=true;
  465. nItemsRead=fread(&ShortValue, SIZE(ShortValue), 1, pFile);
  466. nBytesRead += nItemsRead * SIZE(ShortValue);
  467. resolution_info.hRes=Calculate(ShortValue, SIZE(resolution_info.hRes));
  468. nItemsRead=fread(&IntValue, SIZE(IntValue), 1, pFile);
  469. nBytesRead += nItemsRead * SIZE(IntValue);
  470. resolution_info.hResUnit=Calculate(IntValue, SIZE(resolution_info.hResUnit));
  471. nItemsRead=fread(&ShortValue, SIZE(ShortValue), 1, pFile);
  472. nBytesRead += nItemsRead * SIZE(ShortValue);
  473. resolution_info.widthUnit=Calculate(ShortValue, SIZE(resolution_info.widthUnit));
  474. nItemsRead=fread(&ShortValue, SIZE(ShortValue), 1, pFile);
  475. nBytesRead += nItemsRead * SIZE(ShortValue);
  476. resolution_info.vRes=Calculate(ShortValue, SIZE(resolution_info.vRes));
  477. nItemsRead=fread(&IntValue, SIZE(IntValue), 1, pFile);
  478. nBytesRead += nItemsRead * SIZE(IntValue);
  479. resolution_info.vResUnit=Calculate(IntValue, SIZE(resolution_info.vResUnit));
  480. nItemsRead=fread(&ShortValue, SIZE(ShortValue), 1, pFile);
  481. nBytesRead += nItemsRead * SIZE(ShortValue);
  482. resolution_info.heightUnit=Calculate(ShortValue, SIZE(resolution_info.heightUnit));
  483. }break;
  484. case 1007:
  485. {
  486. mbDisplayInfoFilled=true;
  487. nItemsRead=fread(&ShortValue, SIZE(ShortValue), 1, pFile);
  488. nBytesRead += nItemsRead * SIZE(ShortValue);
  489. display_info.ColourSpace=Calculate(ShortValue, SIZE(display_info.ColourSpace));
  490. for(UInt n=0; n<4; ++n)
  491. {
  492. nItemsRead=fread(&ShortValue, SIZE(ShortValue), 1, pFile);
  493. nBytesRead += nItemsRead * SIZE(ShortValue);
  494. display_info.Colour[n]=Calculate(ShortValue, SIZE(display_info.Colour[n]));
  495. }
  496. nItemsRead=fread(&ShortValue, SIZE(ShortValue), 1, pFile);
  497. nBytesRead += nItemsRead * SIZE(ShortValue);
  498. display_info.Opacity=Calculate(ShortValue, SIZE(display_info.Opacity));
  499. assert (0 <= display_info.Opacity);
  500. assert (100 >= display_info.Opacity);
  501. Byte c[1];
  502. nItemsRead=fread(&c, SIZE(c), 1, pFile);
  503. nBytesRead += nItemsRead * SIZE(c);
  504. (1 == Calculate(c, SIZE(c))) ? display_info.kind=true : display_info.kind=false;
  505. nItemsRead=fread(&c, SIZE(c), 1, pFile);
  506. nBytesRead += nItemsRead * SIZE(c);
  507. display_info.padding=(UInt)Calculate(c, SIZE(c));
  508. assert (0 == display_info.padding);
  509. }break;
  510. case 1034:
  511. {
  512. nItemsRead=fread(&ShortValue, SIZE(ShortValue), 1, pFile);
  513. nBytesRead += nItemsRead * SIZE(ShortValue);
  514. (1 == Calculate(ShortValue, SIZE(ShortValue))) ? mbCopyright=true : mbCopyright=false;
  515. }break;
  516. case 1033:
  517. case 1036:
  518. {
  519. mbThumbNailFilled=true;
  520. nItemsRead=fread(&IntValue, SIZE(IntValue), 1, pFile);
  521. nBytesRead += nItemsRead * SIZE(IntValue);
  522. thumbnail.nFormat=Calculate(IntValue, SIZE(thumbnail.nFormat));
  523. nItemsRead=fread(&IntValue, SIZE(IntValue), 1, pFile);
  524. nBytesRead += nItemsRead * SIZE(IntValue);
  525. thumbnail.nWidth=Calculate(IntValue, SIZE(thumbnail.nWidth));
  526. nItemsRead=fread(&IntValue, SIZE(IntValue), 1, pFile);
  527. nBytesRead += nItemsRead * SIZE(IntValue);
  528. thumbnail.nHeight=Calculate(IntValue, SIZE(thumbnail.nHeight));
  529. nItemsRead=fread(&IntValue, SIZE(IntValue), 1, pFile);
  530. nBytesRead += nItemsRead * SIZE(IntValue);
  531. thumbnail.nWidthBytes=Calculate(IntValue, SIZE(thumbnail.nWidthBytes));
  532. nItemsRead=fread(&IntValue, SIZE(IntValue), 1, pFile);
  533. nBytesRead += nItemsRead * SIZE(IntValue);
  534. thumbnail.nSize=Calculate(IntValue, SIZE(thumbnail.nSize));
  535. nItemsRead=fread(&IntValue, SIZE(IntValue), 1, pFile);
  536. nBytesRead += nItemsRead * SIZE(IntValue);
  537. thumbnail.nCompressedSize=Calculate(IntValue, SIZE(thumbnail.nCompressedSize));
  538. nItemsRead=fread(&ShortValue, SIZE(ShortValue), 1, pFile);
  539. nBytesRead += nItemsRead * SIZE(ShortValue);
  540. thumbnail.nBitPerPixel=Calculate(ShortValue, SIZE(thumbnail.nBitPerPixel));
  541. nItemsRead=fread(&ShortValue, SIZE(ShortValue), 1, pFile);
  542. nBytesRead += nItemsRead * SIZE(ShortValue);
  543. thumbnail.nPlanes=Calculate(ShortValue, SIZE(thumbnail.nPlanes));
  544. Int nTotalData=image_resource.nSize - 28; // header
  545. Byte *buffer=new Byte[nTotalData];
  546. Byte c[1];
  547. if(1033 == image_resource.nID)
  548. {
  549. // In BGR format
  550. for(Int n=0; n<nTotalData; n=n +3)
  551. {
  552. nItemsRead=fread(&c, SIZE(Byte), 1, pFile);
  553. nBytesRead += nItemsRead * SIZE(Byte);
  554. buffer[n+2]=(Byte)Calculate(c, SIZE(Byte));
  555. nItemsRead=fread(&c, SIZE(Byte), 1, pFile);
  556. nBytesRead += nItemsRead * SIZE(Byte);
  557. buffer[n+1]=(Byte)Calculate(c, SIZE(BYTE));
  558. nItemsRead=fread(&c, SIZE(Byte), 1, pFile);
  559. nBytesRead += nItemsRead * SIZE(Byte);
  560. buffer[n]=(Byte)Calculate(c, SIZE(Byte));
  561. }
  562. }
  563. else if(1036 == image_resource.nID)
  564. {
  565. // In RGB format
  566. for(Int n=0; n<nTotalData; ++n)
  567. {
  568. nItemsRead=fread(&c, SIZE(BYTE), 1, pFile);
  569. nBytesRead += nItemsRead * SIZE(BYTE);
  570. buffer[n]=(BYTE)Calculate(c, SIZE(BYTE));
  571. }
  572. }
  573. DeleteN(buffer);
  574. }break;
  575. case 1037:
  576. {
  577. nItemsRead=fread(&IntValue, SIZE(IntValue), 1, pFile);
  578. nBytesRead += nItemsRead * SIZE(IntValue);
  579. mnGlobalAngle=Calculate(IntValue, SIZE(mnGlobalAngle));
  580. }break;
  581. case 1046:
  582. {
  583. nItemsRead=fread(&ShortValue, SIZE(ShortValue), 1, pFile);
  584. nBytesRead += nItemsRead * SIZE(ShortValue);
  585. mnColourCount=Calculate(ShortValue, SIZE(ShortValue));
  586. }break;
  587. case 1047:
  588. {
  589. nItemsRead=fread(&ShortValue, SIZE(ShortValue), 1, pFile);
  590. nBytesRead += nItemsRead * SIZE(ShortValue);
  591. mnTransparentIndex=Calculate(ShortValue, SIZE(ShortValue));
  592. }break;
  593. default:
  594. {
  595. Byte c[1];
  596. for(Int n=0; n<image_resource.nSize; ++n)
  597. {
  598. nItemsRead=fread(&c, SIZE(c), 1, pFile);
  599. nBytesRead += nItemsRead * SIZE(c);
  600. }
  601. }break;
  602. }
  603. }
  604. }
  605. }
  606. return nBytesRead==nTotalBytes;
  607. #endif
  608. }
  609. /******************************************************************************/
  610. Bool PSD::ProccessBuffer(Byte *pData, Image &dest)
  611. {
  612. if(pData)
  613. {
  614. Int nHeight=header_info.nHeight,
  615. nWidth =header_info.nWidth,
  616. bytesPerPixelPerChannel=header_info.nBitsPerPixel/8,
  617. nPixels=nWidth*nHeight,
  618. nTotalBytes=nPixels*bytesPerPixelPerChannel*header_info.nChannels,
  619. nCounter=0,
  620. x=0, y=0;
  621. Dbl max_value=((1<<header_info.nBitsPerPixel)-1);
  622. switch(header_info.nColourMode)
  623. {
  624. case 1: // Grayscale
  625. case 8: // Duotone
  626. {
  627. if(dest.createSoftTry(nWidth, nHeight, 1, (header_info.nBitsPerPixel==32) ? IMAGE_I32 : (header_info.nBitsPerPixel==24) ? IMAGE_I24 : (header_info.nBitsPerPixel==16) ? IMAGE_I16 : IMAGE_L8))
  628. {
  629. for(; nCounter<nTotalBytes; nCounter+=header_info.nChannels*bytesPerPixelPerChannel)
  630. {
  631. UInt u=Calculate(pData+nCounter, bytesPerPixelPerChannel); if(header_info.nBitsPerPixel==32)u=Sat(Pow((Flt&)u, 1.0f/1.75f))*0xFFFFFFFFu;
  632. dest.pixel(x, y, u);
  633. x++; if(x>=nWidth){x=0; y++;}
  634. }
  635. return true;
  636. }
  637. }break;
  638. case 2: // Indexed
  639. {
  640. // pData holds the indices of loop through the palette and set the correct RGB, 8bpp are supported
  641. if(colour_mode_data.ColourData && colour_mode_data.nLength==768 && mnColourCount>0)
  642. if(dest.createSoftTry(nWidth, nHeight, 1, IMAGE_R8G8B8))
  643. {
  644. for(; nCounter<nTotalBytes; ++nCounter)
  645. {
  646. UInt index= pData[nCounter ],
  647. red =colour_mode_data.ColourData[index ],
  648. green=colour_mode_data.ColourData[index+ 256],
  649. blue =colour_mode_data.ColourData[index+2*256];
  650. dest.color(x, y, Color(red, green, blue));
  651. x++; if(x>=nWidth){x=0; y++;}
  652. }
  653. return true;
  654. }
  655. }break;
  656. case 3: // RGB(A), there can be more than 4 channels !!
  657. {
  658. if(dest.createSoftTry(nWidth, nHeight, 1, (header_info.nChannels>=4) ? IMAGE_R8G8B8A8 : IMAGE_R8G8B8))
  659. {
  660. for(; nCounter<nTotalBytes; nCounter=nCounter + header_info.nChannels * bytesPerPixelPerChannel)
  661. {
  662. UInt red = Calculate(pData+nCounter , bytesPerPixelPerChannel) ,
  663. green= Calculate(pData+nCounter+ bytesPerPixelPerChannel, bytesPerPixelPerChannel) ,
  664. blue = Calculate(pData+nCounter+2*bytesPerPixelPerChannel, bytesPerPixelPerChannel) ,
  665. alpha=((header_info.nChannels>=4) ? Calculate(pData+nCounter+3*bytesPerPixelPerChannel, bytesPerPixelPerChannel) : 0);
  666. if(bytesPerPixelPerChannel==4) // Flt
  667. {
  668. red =RoundU(Pow(Sat((Flt&)red ), 1/2.12f)*255);
  669. green=RoundU(Pow(Sat((Flt&)green), 1/2.12f)*255);
  670. blue =RoundU(Pow(Sat((Flt&)blue ), 1/2.12f)*255);
  671. }else
  672. REP(bytesPerPixelPerChannel-1){red>>=8; green>>=8; blue>>=8; alpha>>=8;}
  673. dest.color(x, y, Color(red, green, blue, alpha));
  674. x++; if(x>=nWidth){x=0; y++;}
  675. }
  676. return true;
  677. }
  678. }break;
  679. case 4: // CMYK
  680. {
  681. if(dest.createSoftTry(nWidth, nHeight, 1, IMAGE_R8G8B8))
  682. {
  683. for(; nCounter<nTotalBytes; nCounter+=header_info.nChannels*bytesPerPixelPerChannel)
  684. {
  685. Dbl c=1-Calculate(pData+nCounter , bytesPerPixelPerChannel)/max_value,
  686. m=1-Calculate(pData+nCounter +bytesPerPixelPerChannel, bytesPerPixelPerChannel)/max_value,
  687. Y=1-Calculate(pData+nCounter+2*bytesPerPixelPerChannel, bytesPerPixelPerChannel)/max_value,
  688. k=1-Calculate(pData+nCounter+3*bytesPerPixelPerChannel, bytesPerPixelPerChannel)/max_value;
  689. Int red, green, blue; CMYKToRGB(c, m, Y, k, red, green, blue);
  690. dest.color(x, y, Color(red, green, blue));
  691. x++; if(x>=nWidth){x=0; y++;}
  692. }
  693. return true;
  694. }
  695. }break;
  696. case 7: // Multichannel
  697. {
  698. if(header_info.nChannels==1) // for now support just one channel
  699. if(dest.createSoftTry(nWidth, nHeight, 1, IMAGE_L8))
  700. {
  701. for(; nCounter<nTotalBytes; nCounter+=header_info.nChannels*bytesPerPixelPerChannel)
  702. {
  703. Dbl a=Calculate(pData+nCounter, bytesPerPixelPerChannel)/max_value;
  704. dest.pixel(x, y, RoundU(a*255));
  705. x++; if(x>=nWidth){x=0; y++;}
  706. }
  707. return true;
  708. }
  709. }break;
  710. case 9: // LAB
  711. {
  712. if(dest.createSoftTry(nWidth, nHeight, 1, (header_info.nChannels==4) ? IMAGE_R8G8B8A8 : IMAGE_R8G8B8))
  713. {
  714. Dbl L_coef=max_value/100.0,
  715. a_coef=max_value/256.0,
  716. b_coef=max_value/256.0;
  717. for(; nCounter<nTotalBytes; nCounter+=header_info.nChannels*bytesPerPixelPerChannel)
  718. {
  719. Dbl L = Calculate(pData+nCounter , bytesPerPixelPerChannel)/L_coef ,
  720. A = Calculate(pData+nCounter+ bytesPerPixelPerChannel, bytesPerPixelPerChannel)/a_coef-128 ,
  721. B = Calculate(pData+nCounter+2*bytesPerPixelPerChannel, bytesPerPixelPerChannel)/b_coef-128 ;
  722. UInt alpha=((header_info.nChannels==4) ? Calculate(pData+nCounter+3*bytesPerPixelPerChannel, bytesPerPixelPerChannel) : 0);
  723. Int red, green, blue; LABToRGB(L, A, B, red, green, blue); REP(bytesPerPixelPerChannel-1)alpha>>=8;
  724. dest.color(x, y, Color(red, green, blue, alpha));
  725. x++; if(x>=nWidth){x=0; y++;}
  726. }
  727. return true;
  728. }
  729. }break;
  730. }
  731. }
  732. return false;
  733. }
  734. /******************************************************************************/
  735. Bool PSD::ReadImageData(File &f, Image &dest)
  736. {
  737. Bool ok=false;
  738. switch(GetU16(f))
  739. {
  740. case 0: // raw data
  741. {
  742. Int nWidth=header_info.nWidth;
  743. Int nHeight=header_info.nHeight;
  744. Int bytesPerPixelPerChannel=header_info.nBitsPerPixel/8;
  745. Int nPixels=nWidth*nHeight;
  746. Int nTotalBytes=nPixels*bytesPerPixelPerChannel*header_info.nChannels;
  747. Int nBytesRead=0;
  748. Byte *pData=null;
  749. switch(header_info.nColourMode)
  750. {
  751. case 1: // Grayscale
  752. case 7: // Multichannel
  753. case 8: // Duotone
  754. {
  755. pData=new Byte[nTotalBytes];
  756. nBytesRead=f.getReturnSize(pData, nTotalBytes);
  757. }break;
  758. case 2: // Indexed
  759. {
  760. if(mnColourCount>0 && colour_mode_data.ColourData!=0)
  761. {
  762. pData=new Byte[nTotalBytes];
  763. nBytesRead=f.getReturnSize(pData, nTotalBytes);
  764. }
  765. }break;
  766. case 3: // RGB
  767. case 4: // CMYK
  768. case 9: // LAB
  769. {
  770. pData=new Byte[nTotalBytes];
  771. for(Int nColour=0; nColour<header_info.nChannels ; ++nColour)
  772. for(Int nPos =0; nPos <nPixels ; ++nPos )
  773. for(Int nByte =0; nByte <bytesPerPixelPerChannel; ++nByte )
  774. {
  775. pData[nPos*header_info.nChannels*bytesPerPixelPerChannel + nColour*bytesPerPixelPerChannel + nByte]=f.getByte();
  776. nBytesRead++;
  777. }
  778. }break;
  779. }
  780. if(nBytesRead==nTotalBytes)ok=ProccessBuffer(pData, dest);
  781. DeleteN(pData);
  782. }break;
  783. case 1: // RLE compression
  784. {
  785. Int nWidth=header_info.nWidth;
  786. Int nHeight=header_info.nHeight;
  787. Int bytesPerPixelPerChannel=header_info.nBitsPerPixel/8;
  788. Int nPixels=nWidth*nHeight;
  789. Int nTotalBytes=nPixels*bytesPerPixelPerChannel*header_info.nChannels;
  790. Byte *pData=new Byte[nTotalBytes];
  791. Byte *p=pData;
  792. // The RLE-compressed data is preceeded by a 2-byte data count for each row in the data, which we're going to just skip
  793. f.skip(nHeight*header_info.nChannels*2);
  794. for(Int channel=0; channel<header_info.nChannels; channel++)
  795. {
  796. // Read the RLE data.
  797. Int count=0;
  798. while(count<nPixels)
  799. {
  800. Int len=f.getByte();
  801. if( len<128)
  802. {
  803. len++;
  804. count+=len;
  805. while(len)
  806. {
  807. *p++=f.getByte();
  808. len--;
  809. }
  810. }else
  811. if(len>128)
  812. {
  813. // Next -len+1 bytes in the dest are replicated from next source byte, Interpret len as a negative 8-bit Int
  814. len^=0xFF;
  815. len+=2;
  816. Byte value=f.getByte();
  817. count+=len;
  818. while(len)
  819. {
  820. *p++=value;
  821. len--;
  822. }
  823. }/*else
  824. if(len==128)
  825. {
  826. // Do nothing
  827. }*/
  828. }
  829. }
  830. Byte *pSrc =pData,
  831. *pDest=new Byte[nTotalBytes];
  832. Int nPixelCounter=0;
  833. for(Int nColour=0; nColour<header_info.nChannels; ++nColour)
  834. {
  835. nPixelCounter=nColour*bytesPerPixelPerChannel;
  836. for(Int nPos=0; nPos<nPixels; nPos++)
  837. {
  838. CopyFast(pDest+nPixelCounter, pSrc, bytesPerPixelPerChannel);
  839. pSrc++;
  840. nPixelCounter+=header_info.nChannels*bytesPerPixelPerChannel;
  841. }
  842. }
  843. ok=ProccessBuffer(pDest, dest);
  844. DeleteN(pData);
  845. DeleteN(pDest);
  846. }break;
  847. case 2: break; // ZIP without prediction, no specification
  848. case 3: break; // ZIP with prediction, no specification
  849. default: break; // unknown format
  850. }
  851. return ok;
  852. }
  853. /******************************************************************************/
  854. static Color UnblendWhite(Color c)
  855. {
  856. // original*alpha + white*(1-alpha) = c
  857. // original = (c - white*(1-alpha))/alpha
  858. if(c.a)
  859. {
  860. Int a_2=c.a/2, a1=255-c.a;
  861. c.r=Mid((255*(c.r-a1)+a_2)/c.a, 0, 255);
  862. c.g=Mid((255*(c.g-a1)+a_2)/c.a, 0, 255);
  863. c.b=Mid((255*(c.b-a1)+a_2)/c.a, 0, 255);
  864. }
  865. return c;
  866. }
  867. static Color Unblend(Color c, C Color &back)
  868. {
  869. // original*alpha + back*(1-alpha) = c
  870. // original = (c - back*(1-alpha))/alpha
  871. // original = (c - back + back*alpha)/alpha
  872. // original = (c - back)/alpha + back
  873. if(c.a)
  874. {
  875. Int a_2=c.a/2;
  876. c.r=Mid((255*(c.r-back.r)+a_2)/c.a+back.r, 0, 255);
  877. c.g=Mid((255*(c.g-back.g)+a_2)/c.a+back.g, 0, 255);
  878. c.b=Mid((255*(c.b-back.b)+a_2)/c.a+back.b, 0, 255);
  879. }
  880. return c;
  881. }
  882. #endif
  883. /******************************************************************************/
  884. Bool Image::ImportPSD(File &f)
  885. {
  886. del();
  887. #if SUPPORT_PSD
  888. PSD psd;
  889. if(psd.ReadHeader (f, psd.header_info))
  890. if(psd.ReadColourModeData (f, psd.colour_mode_data))
  891. if(psd.ReadImageResource (f, psd.image_resource))
  892. if(psd.ReadLayerAndMaskInfoSection(f))
  893. if(psd.ReadImageData (f, T))
  894. {
  895. if(psd.merged_alpha && ImageTI[hwType()].a) // PSD's are blended on white background
  896. {
  897. REPD(y, h())
  898. REPD(x, w())color(x, y, UnblendWhite(color(x, y)));
  899. transparentToNeighbor();
  900. }
  901. return true;
  902. }
  903. #endif
  904. return false;
  905. }
  906. Bool Image::ImportPSD(C Str &name)
  907. {
  908. #if SUPPORT_PSD
  909. File f; if(f.readTry(name))return ImportPSD(f);
  910. #endif
  911. del(); return false;
  912. }
  913. /******************************************************************************/
  914. }
  915. /******************************************************************************/