sparc.h 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726
  1. /*
  2. * UNPUBLISHED -- Rights reserved under the copyright laws of the
  3. * United States. Use of a copyright notice is precautionary only and
  4. * does not imply publication or disclosure.
  5. *
  6. * THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION
  7. * OF VICARIOUS VISIONS, INC. ANY DUPLICATION, MODIFICATION,
  8. * DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR
  9. * EXPRESS WRITTEN PERMISSION OF VICARIOUS VISIONS, INC.
  10. */
  11. /*
  12. AUTHOR: Dave Calvin
  13. CREATED: 2002-05-07
  14. SParse ARray Compressor. Given an array, this class reduces the memory
  15. needed to store the array by eliminating the most-frequently used element.
  16. The remaining elements are increased in size by one integer.
  17. If the compressed data would be larger than the original data, the
  18. original data is stored as is.
  19. Compression is O(2N) where N is the number of elements to compress.
  20. Decompression is O(log M + N) where M is the number of elements after
  21. compression (CompressedLength()) and N is the number of elements to decompress.
  22. Decompression is O(1) when the same or smaller amount of data is requested as
  23. the last decompression.
  24. The pointer returned by Decompress() is valid until the class is destroyed
  25. or a new call is made to Compress() or Decompress().
  26. Elements must define operator==, operator!=, and sizeof.
  27. */
  28. #ifndef __SPARC_H
  29. #define __SPARC_H
  30. #ifdef _GAMECUBE
  31. #define SPARC_BIG_ENDIAN
  32. #endif
  33. //Bigger than a short, smaller than an int.
  34. #pragma pack(push, 1)
  35. struct NotSoShort
  36. {
  37. unsigned char bytes[3];
  38. NotSoShort(void) {}
  39. NotSoShort(unsigned int source) {
  40. #ifdef SPARC_BIG_ENDIAN
  41. bytes[2] = source & 0xFF;
  42. bytes[1] = (source >> 8) & 0xFF;
  43. bytes[0] = (source >> 16) & 0xFF;
  44. #else
  45. bytes[0] = source & 0xFF;
  46. bytes[1] = (source >> 8) & 0xFF;
  47. bytes[2] = (source >> 16) & 0xFF;
  48. #endif
  49. }
  50. inline unsigned int GetValue(void) {
  51. #ifdef SPARC_BIG_ENDIAN
  52. return (bytes[0] << 16) | (bytes[1] << 8) | bytes[2];
  53. #else
  54. return (bytes[2] << 16) | (bytes[1] << 8) | bytes[0];
  55. #endif
  56. }
  57. inline bool operator==(unsigned int cmp) {
  58. #ifdef SPARC_BIG_ENDIAN
  59. return cmp == ((*(unsigned int*)bytes) >> 8);
  60. #else
  61. return cmp == ((*(unsigned int*)bytes) & 0x00FFFFFF);
  62. #endif
  63. }
  64. bool operator<(unsigned int cmp) {
  65. unsigned int tmp = *(unsigned int*)bytes;
  66. #ifdef SPARC_BIG_ENDIAN
  67. tmp >>= 8;
  68. #else
  69. tmp &= 0x00FFFFFF;
  70. #endif
  71. return tmp < cmp;
  72. }
  73. bool operator<=(unsigned int cmp) {
  74. unsigned int tmp = *(unsigned int*)bytes;
  75. #ifdef SPARC_BIG_ENDIAN
  76. tmp >>= 8;
  77. #else
  78. tmp &= 0x00FFFFFF;
  79. #endif
  80. return tmp <= cmp;
  81. }
  82. bool operator>(unsigned int cmp) {
  83. unsigned int tmp = *(unsigned int*)bytes;
  84. #ifdef SPARC_BIG_ENDIAN
  85. tmp >>= 8;
  86. #else
  87. tmp &= 0x00FFFFFF;
  88. #endif
  89. return tmp > cmp;
  90. }
  91. };
  92. //Compressed data is made up of these elements.
  93. template <class T, class U>
  94. struct SPARCElement
  95. {
  96. T data;
  97. U offset;
  98. };
  99. #pragma pack(pop)
  100. inline unsigned int SPARC_SWAP32(unsigned int x, bool doSwap) {
  101. if (doSwap) {
  102. return ((unsigned int)( ( (x & 0xff000000) >> 24)
  103. + ( (x & 0x00ff0000) >> 8 )
  104. + ( (x & 0x0000ff00) << 8 )
  105. + ( (x & 0x000000ff) << 24 ) ));
  106. }
  107. return x;
  108. }
  109. inline NotSoShort SPARC_SWAP24(NotSoShort x, bool doSwap) {
  110. if (doSwap) {
  111. x.bytes[0] ^= x.bytes[2];
  112. x.bytes[2] ^= x.bytes[0];
  113. x.bytes[0] ^= x.bytes[2];
  114. }
  115. return x;
  116. }
  117. inline unsigned short SPARC_SWAP16(unsigned short x, bool doSwap) {
  118. if (doSwap) {
  119. return ((unsigned short)( ( (x & 0xff00) >> 8)
  120. + ( (x & 0x00ff) << 8 ) ));
  121. }
  122. return x;
  123. }
  124. //The core of the SPARC system. T is the data type to be compressed.
  125. //U is the data type needed to store offsets information in the compressed
  126. //data. Smaller U makes for better compression but bigger data requires
  127. //larger U.
  128. template <class T, class U>
  129. class SPARCCore
  130. {
  131. private:
  132. //Using compression or just storing clear data?
  133. bool compressionUsed;
  134. //Compressed data and its length.
  135. SPARCElement<T, U> *compressedData;
  136. unsigned int compressedLength;
  137. //Decompression cache.
  138. T *decompressedData;
  139. unsigned int decompressedOffset;
  140. unsigned int decompressedLength;
  141. //Element which was removed to compress.
  142. T removedElement;
  143. //Length of original data before compression.
  144. unsigned int originalLength;
  145. //Memory allocators.
  146. void* (*Allocator)(unsigned int size);
  147. void (*Deallocator)(void *ptr);
  148. //Destroy all allocated memory.
  149. void Cleanup(void) {
  150. if(compressedData) {
  151. if(Deallocator) {
  152. Deallocator(compressedData);
  153. } else {
  154. delete [] compressedData;
  155. }
  156. compressedData = NULL;
  157. }
  158. if(decompressedData) {
  159. if(Deallocator) {
  160. Deallocator(decompressedData);
  161. } else {
  162. delete [] decompressedData;
  163. }
  164. decompressedData = NULL;
  165. }
  166. }
  167. void Init(void) {
  168. compressionUsed = false;
  169. compressedData = NULL;
  170. originalLength = 0;
  171. compressedLength = 0;
  172. decompressedData = NULL;
  173. decompressedOffset = 0;
  174. decompressedLength = 0;
  175. }
  176. //Binary search for the compressed element most closely matching 'offset'.
  177. SPARCElement<T, U> *FindDecompStart(unsigned int offset)
  178. {
  179. unsigned int startPoint = compressedLength / 2;
  180. unsigned int divisor = 4;
  181. unsigned int leap;
  182. while(1) {
  183. if(compressedData[startPoint].offset <= offset &&
  184. compressedData[startPoint+1].offset > offset) {
  185. if(compressedData[startPoint].offset == offset) {
  186. return &compressedData[startPoint];
  187. } else {
  188. return &compressedData[startPoint+1];
  189. }
  190. }
  191. leap = compressedLength / divisor;
  192. if(leap < 1) {
  193. leap = 1;
  194. } else {
  195. divisor *= 2;
  196. }
  197. if(compressedData[startPoint].offset > offset) {
  198. startPoint -= leap;
  199. } else {
  200. startPoint += leap;
  201. }
  202. }
  203. }
  204. public:
  205. SPARCCore(void) {
  206. Init();
  207. Allocator = NULL;
  208. Deallocator = NULL;
  209. }
  210. ~SPARCCore(void) {
  211. Cleanup();
  212. }
  213. void SetAllocator(void* (*alloc)(unsigned int size),
  214. void (*dealloc)(void *ptr)) {
  215. Allocator = alloc;
  216. Deallocator = dealloc;
  217. }
  218. //Just store the array without compression.
  219. unsigned int Store(const T *array, unsigned int length) {
  220. //Destroy old data.
  221. Cleanup();
  222. Init();
  223. //Allocate memory and copy array.
  224. if(Allocator) {
  225. decompressedData = (T*)Allocator(length * sizeof(T));
  226. } else {
  227. decompressedData = new T[length];
  228. }
  229. compressedLength = length;
  230. memcpy(decompressedData, array, sizeof(T) * length);
  231. //Set length.
  232. originalLength = length;
  233. return CompressedSize();
  234. }
  235. //Load compressed data directly.
  236. unsigned int Load(const char *array, unsigned int length) {
  237. //Destroy old data.
  238. Cleanup();
  239. Init();
  240. //Restore some attributes.
  241. compressionUsed = (bool)*array++;
  242. assert(sizeof(T) == 1); //For now only support characters.
  243. removedElement = *(T*)array;
  244. array += sizeof(T);
  245. originalLength = *(unsigned int*)array;
  246. array += sizeof(unsigned int);
  247. compressedLength = *(unsigned int*)array;
  248. array += sizeof(unsigned int);
  249. //Allocate memory and copy array.
  250. if (compressionUsed) {
  251. if(Allocator) {
  252. compressedData = (SPARCElement<T, U>*)
  253. Allocator(compressedLength * sizeof(SPARCElement<T, U>));
  254. } else {
  255. compressedData = new SPARCElement<T, U>[compressedLength];
  256. }
  257. memcpy(compressedData, array,
  258. compressedLength * sizeof(SPARCElement<T, U>));
  259. }
  260. else {
  261. if(Allocator) {
  262. decompressedData = (T*)Allocator(
  263. compressedLength * sizeof(T));
  264. } else {
  265. decompressedData = new T[compressedLength];
  266. }
  267. memcpy(decompressedData, array, compressedLength * sizeof(T));
  268. }
  269. return CompressedSize();
  270. }
  271. //Save state for later restoration.
  272. unsigned int Save(char *array, unsigned int length, bool doSwap) {
  273. //Figure out how much space is needed.
  274. unsigned int size = sizeof(char) + sizeof(T) +
  275. sizeof(unsigned int) + sizeof(unsigned int);
  276. if (compressionUsed) {
  277. size += compressedLength * sizeof(SPARCElement<T, U>);
  278. }
  279. else {
  280. size += compressedLength * sizeof(T);
  281. }
  282. assert(length >= size);
  283. //Save some attributes.
  284. *array++ = (char)compressionUsed;
  285. assert(sizeof(T) == 1); //For now only support characters.
  286. *(T*)array = removedElement;
  287. array += sizeof(T);
  288. *(unsigned int*)array = SPARC_SWAP32(originalLength, doSwap);
  289. array += sizeof(unsigned int);
  290. *(unsigned int*)array = SPARC_SWAP32(compressedLength, doSwap);
  291. array += sizeof(unsigned int);
  292. //Store compressed data (or uncompressed data if none exists)
  293. if (compressionUsed) {
  294. for (unsigned int i = 0; i < compressedLength; ++i) {
  295. //Copy the data element. For now only support characters.
  296. ((SPARCElement<T, U> *)array)[i].data = compressedData[i].data;
  297. //Copy the offset to the next unique element.
  298. if (sizeof(U) == 1) {
  299. ((SPARCElement<T, U> *)array)[i].offset =
  300. compressedData[i].offset;
  301. }
  302. else if (sizeof(U) == 2) {
  303. ((SPARCElement<T, unsigned short> *)array)[i].offset =
  304. SPARC_SWAP16(*(unsigned short*)&compressedData[i].offset,
  305. doSwap);
  306. }
  307. else if (sizeof(U) == 3) {
  308. ((SPARCElement<T, NotSoShort> *)array)[i].offset =
  309. SPARC_SWAP24(*(NotSoShort*)&compressedData[i].offset,
  310. doSwap);
  311. }
  312. else if (sizeof(U) == 4) {
  313. ((SPARCElement<T, unsigned int> *)array)[i].offset =
  314. SPARC_SWAP32(*(unsigned int*)&compressedData[i].offset,
  315. doSwap);
  316. }
  317. }
  318. }
  319. else {
  320. memcpy(array, decompressedData, compressedLength * sizeof(T));
  321. }
  322. return size;
  323. }
  324. //Compresses this array, returns the compressed size. Compresses
  325. //by eliminating the given element.
  326. unsigned int Compress(const T *array, unsigned int length, T removal) {
  327. unsigned int i;
  328. unsigned int numRemove = 0;
  329. SPARCElement<T, U> *compress;
  330. //Destroy old data.
  331. Cleanup();
  332. Init();
  333. //Count number of elements to remove. Can't remove first or
  334. //last element (prevents boundary conditions).
  335. for(i=1; i<length-1; i++) {
  336. if(array[i] == removal) {
  337. numRemove++;
  338. }
  339. }
  340. compressedLength = length - numRemove;
  341. originalLength = length;
  342. //If we're going to allocate more memory than was originally used,
  343. //just store the data.
  344. if(sizeof(SPARCElement<T, U>) * compressedLength >=
  345. sizeof(T) * length) {
  346. Store(array, length);
  347. return CompressedSize();
  348. }
  349. //Allocate memory for compressed elements.
  350. if(Allocator) {
  351. compressedData = (SPARCElement<T, U>*)
  352. Allocator(compressedLength * sizeof(SPARCElement<T, U>));
  353. } else {
  354. compressedData = new SPARCElement<T, U>[compressedLength];
  355. }
  356. compressionUsed = true;
  357. //Fill compressed array. First and last elements go in no matter
  358. //what.
  359. compressedData[0].data = array[0];
  360. compressedData[0].offset = 0;
  361. compress = &compressedData[1];
  362. for(i=1; i<length-1; i++) {
  363. if(array[i] != removal) {
  364. compress->data = array[i];
  365. compress->offset = i;
  366. compress++;
  367. }
  368. }
  369. compress->data = array[i];
  370. compress->offset = i;
  371. //Store removal value for decompression purposes.
  372. removedElement = removal;
  373. //Store original length for bounds checking.
  374. originalLength = length;
  375. //Return the compressed size.
  376. return CompressedSize();
  377. }
  378. //Get the compressed data size in bytes, or 0 if nothing stored.
  379. unsigned int CompressedSize(void) {
  380. return compressedLength * sizeof(SPARCElement<T, U>);
  381. }
  382. //Get the decompressed data starting at offset and ending at
  383. //offset + length. Returns NULL on error.
  384. const T *Decompress(unsigned int offset, unsigned int length) {
  385. SPARCElement<T, U> *decomp = NULL;
  386. unsigned int i;
  387. //If data isn't compressed, just return a pointers.
  388. if(!compressionUsed) {
  389. return decompressedData + offset;
  390. }
  391. //If last decompression falls within offset and length, just return
  392. //a pointer.
  393. if(decompressedData && decompressedOffset <= offset &&
  394. decompressedOffset + decompressedLength >= offset + length) {
  395. return decompressedData + offset - decompressedOffset;
  396. }
  397. //Allocate new space for decompression if length has changed.
  398. if(length != decompressedLength) {
  399. //Destroy old data first.
  400. if(decompressedData) {
  401. if(Deallocator) {
  402. Deallocator(decompressedData);
  403. } else {
  404. delete [] decompressedData;
  405. }
  406. }
  407. if(Allocator) {
  408. decompressedData = (T*)Allocator(length * sizeof(T));
  409. } else {
  410. decompressedData = new T[length];
  411. }
  412. }
  413. decompressedOffset = offset;
  414. decompressedLength = length;
  415. //Find position to start decompressing from.
  416. decomp = FindDecompStart(offset);
  417. if(!decomp) { //should never happen
  418. assert(0);
  419. return NULL;
  420. }
  421. //Decompress the data.
  422. for(i=0; i < length; i++) {
  423. if(decomp->offset == i + offset) {
  424. decompressedData[i] = decomp->data;
  425. decomp++;
  426. } else {
  427. decompressedData[i] = removedElement;
  428. }
  429. }
  430. return decompressedData;
  431. }
  432. };
  433. //The user-interface to SPARC. Automatically selects the best core based
  434. //on data size.
  435. template <class T>
  436. class SPARC
  437. {
  438. private:
  439. void *core;
  440. unsigned char offsetBytes;
  441. //Memory allocators.
  442. void* (*Allocator)(unsigned int size);
  443. void (*Deallocator)(void *ptr);
  444. public:
  445. SPARC(void) {
  446. core = NULL;
  447. offsetBytes = 0;
  448. Allocator = NULL;
  449. Deallocator = NULL;
  450. }
  451. ~SPARC(void) {
  452. Release();
  453. };
  454. void SetAllocator(void* (*alloc)(unsigned int size),
  455. void (*dealloc)(void *ptr)) {
  456. Allocator = alloc;
  457. Deallocator = dealloc;
  458. }
  459. //Select a core, cast it to the right type and return the size.
  460. unsigned int CompressedSize(void) {
  461. if(!core) {
  462. return 0;
  463. }
  464. switch(offsetBytes) {
  465. case 1:
  466. return ((SPARCCore<T, unsigned char>*)core)->CompressedSize();
  467. case 2:
  468. return ((SPARCCore<T, unsigned short>*)core)->CompressedSize();
  469. case 3:
  470. return ((SPARCCore<T, NotSoShort>*)core)->CompressedSize();
  471. case 4:
  472. return ((SPARCCore<T, unsigned int>*)core)->CompressedSize();
  473. }
  474. return 0;
  475. }
  476. //Always use the same core type since we won't be compressing.
  477. unsigned int Store(const T *array, unsigned int length)
  478. {
  479. Release();
  480. offsetBytes = 1;
  481. core = new SPARCCore<T, unsigned char>;
  482. ((SPARCCore<T, unsigned char>*)core)->
  483. SetAllocator(Allocator, Deallocator);
  484. return ((SPARCCore<T, unsigned char>*)core)-> Store(array, length);
  485. }
  486. //Load compressed data directly.
  487. unsigned int Load(const char *array, unsigned int length) {
  488. Release();
  489. offsetBytes = *array++;
  490. switch (offsetBytes) {
  491. case 1:
  492. core = new SPARCCore<T, unsigned char>;
  493. ((SPARCCore<T, unsigned char>*)core)->
  494. SetAllocator(Allocator, Deallocator);
  495. return ((SPARCCore<T, unsigned char>*)core)->
  496. Load(array, length-1);
  497. case 2:
  498. core = new SPARCCore<T, unsigned short>;
  499. ((SPARCCore<T, unsigned short>*)core)->
  500. SetAllocator(Allocator, Deallocator);
  501. return ((SPARCCore<T, unsigned short>*)core)->
  502. Load(array, length-1);
  503. case 3:
  504. core = new SPARCCore<T, NotSoShort>;
  505. ((SPARCCore<T, NotSoShort>*)core)->
  506. SetAllocator(Allocator, Deallocator);
  507. return ((SPARCCore<T, NotSoShort>*)core)->
  508. Load(array, length-1);
  509. case 4:
  510. core = new SPARCCore<T, unsigned int>;
  511. ((SPARCCore<T, unsigned int>*)core)->
  512. SetAllocator(Allocator, Deallocator);
  513. return ((SPARCCore<T, unsigned int>*)core)->
  514. Load(array, length-1);
  515. default:
  516. assert(false);
  517. return 0;
  518. }
  519. }
  520. //Save compressed data into array.
  521. unsigned int Save(char *array, unsigned int length, bool doSwap) {
  522. *array++ = offsetBytes;
  523. switch (offsetBytes) {
  524. case 1:
  525. return ((SPARCCore<T, unsigned char>*)core)->
  526. Save(array, length-1, doSwap);
  527. case 2:
  528. return ((SPARCCore<T, unsigned short>*)core)->
  529. Save(array, length-1, doSwap);
  530. case 3:
  531. return ((SPARCCore<T, NotSoShort>*)core)->
  532. Save(array, length-1, doSwap);
  533. case 4:
  534. return ((SPARCCore<T, unsigned int>*)core)->
  535. Save(array, length-1, doSwap);
  536. default:
  537. assert(false);
  538. return 0;
  539. }
  540. }
  541. //Create the smallest core possible for the given data.
  542. unsigned int Compress(const T *array, unsigned int length, T removal) {
  543. Release();
  544. if(length < 256) {
  545. offsetBytes = 1;
  546. core = new SPARCCore<T, unsigned char>;
  547. ((SPARCCore<T, unsigned char>*)core)->
  548. SetAllocator(Allocator, Deallocator);
  549. return ((SPARCCore<T, unsigned char>*)core)->
  550. Compress(array, length, removal);
  551. } else if(length < 65536) {
  552. offsetBytes = 2;
  553. core = new SPARCCore<T, unsigned short>;
  554. ((SPARCCore<T, unsigned short>*)core)->
  555. SetAllocator(Allocator, Deallocator);
  556. return ((SPARCCore<T, unsigned short>*)core)->
  557. Compress(array, length, removal);
  558. } else if(length < 16777216) {
  559. offsetBytes = 3;
  560. core = new SPARCCore<T, NotSoShort>;
  561. ((SPARCCore<T, NotSoShort>*)core)->
  562. SetAllocator(Allocator, Deallocator);
  563. return ((SPARCCore<T, NotSoShort>*)core)->
  564. Compress(array, length, removal);
  565. } else {
  566. offsetBytes = 4;
  567. core = new SPARCCore<T, unsigned int>;
  568. ((SPARCCore<T, unsigned int>*)core)->
  569. SetAllocator(Allocator, Deallocator);
  570. return ((SPARCCore<T, unsigned int>*)core)->
  571. Compress(array, length, removal);
  572. }
  573. }
  574. //Cast to the correct core type and decompress.
  575. const T *Decompress(unsigned int offset, unsigned int length) {
  576. if(!core) {
  577. return NULL;
  578. }
  579. switch(offsetBytes) {
  580. case 1:
  581. return ((SPARCCore<T, unsigned char>*)core)->
  582. Decompress(offset, length);
  583. case 2:
  584. return ((SPARCCore<T, unsigned short>*)core)->
  585. Decompress(offset, length);
  586. case 3:
  587. return ((SPARCCore<T, NotSoShort>*)core)->
  588. Decompress(offset, length);
  589. case 4:
  590. return ((SPARCCore<T, unsigned int>*)core)->
  591. Decompress(offset, length);
  592. }
  593. return NULL;
  594. }
  595. //Destroy all compressed data and the current decompressed buffer.
  596. void Release(void) {
  597. if(core) {
  598. switch(offsetBytes) {
  599. case 1:
  600. delete (SPARCCore<T, unsigned char>*)core;
  601. break;
  602. case 2:
  603. delete (SPARCCore<T, unsigned short>*)core;
  604. break;
  605. case 3:
  606. delete (SPARCCore<T, NotSoShort>*)core;
  607. break;
  608. case 4:
  609. delete (SPARCCore<T, unsigned int>*)core;
  610. break;
  611. }
  612. core = NULL;
  613. }
  614. }
  615. };
  616. #endif