tif_stream.cxx
上传用户:looem2003
上传日期:2014-07-20
资源大小:13733k
文件大小:7k
源码类别:

打印编程

开发平台:

Visual C++

  1. /* $Id: tif_stream.cxx,v 1.5 2005/07/26 08:11:13 dron Exp $ */
  2. /*
  3.  * Copyright (c) 1988-1996 Sam Leffler
  4.  * Copyright (c) 1991-1996 Silicon Graphics, Inc.
  5.  *
  6.  * Permission to use, copy, modify, distribute, and sell this software and 
  7.  * its documentation for any purpose is hereby granted without fee, provided
  8.  * that (i) the above copyright notices and this permission notice appear in
  9.  * all copies of the software and related documentation, and (ii) the names of
  10.  * Sam Leffler and Silicon Graphics may not be used in any advertising or
  11.  * publicity relating to the software without the specific, prior written
  12.  * permission of Sam Leffler and Silicon Graphics.
  13.  * 
  14.  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
  15.  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
  16.  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
  17.  * 
  18.  * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
  19.  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
  20.  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  21.  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
  22.  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
  23.  * OF THIS SOFTWARE.
  24.  */
  25. /*
  26.  * TIFF Library UNIX-specific Routines.
  27.  */
  28. #include "tiffiop.h"
  29. #include <iostream>
  30. using namespace std;
  31. class tiffis_data
  32. {
  33.   public:
  34. istream *myIS;
  35.         long myStreamStartPos;
  36. };
  37. class tiffos_data
  38. {
  39.   public:
  40. ostream *myOS;
  41. long myStreamStartPos;
  42. };
  43. static tsize_t
  44. _tiffosReadProc(thandle_t, tdata_t, tsize_t)
  45. {
  46.         return 0;
  47. }
  48. static tsize_t
  49. _tiffisReadProc(thandle_t fd, tdata_t buf, tsize_t size)
  50. {
  51.         tiffis_data *data = (tiffis_data *)fd;
  52.         data->myIS->read((char *)buf, (int)size);
  53.         return data->myIS->gcount();
  54. }
  55. static tsize_t
  56. _tiffosWriteProc(thandle_t fd, tdata_t buf, tsize_t size)
  57. {
  58. tiffos_data *data = (tiffos_data *)fd;
  59. ostream *os = data->myOS;
  60. int pos = os->tellp();
  61. os->write((const char *)buf, size);
  62. return ((int)os->tellp()) - pos;
  63. }
  64. static tsize_t
  65. _tiffisWriteProc(thandle_t, tdata_t, tsize_t)
  66. {
  67. return 0;
  68. }
  69. static toff_t
  70. _tiffosSeekProc(thandle_t fd, toff_t off, int whence)
  71. {
  72. tiffos_data *data = (tiffos_data *)fd;
  73. ostream *os = data->myOS;
  74. // if the stream has already failed, don't do anything
  75. if( os->fail() )
  76. return os->tellp();
  77. switch(whence) {
  78. case SEEK_SET:
  79.     os->seekp(data->myStreamStartPos + off, ios::beg);
  80. break;
  81. case SEEK_CUR:
  82. os->seekp(off, ios::cur);
  83. break;
  84. case SEEK_END:
  85. os->seekp(off, ios::end);
  86. break;
  87. }
  88. // Attempt to workaround problems with seeking past the end of the
  89. // stream.  ofstream doesn't have a problem with this but
  90. // ostrstream/ostringstream does. In that situation, add intermediate
  91. // '' characters.
  92. if( os->fail() ) {
  93. ios::iostate old_state;
  94. toff_t origin;
  95. old_state = os->rdstate();
  96. // reset the fail bit or else tellp() won't work below
  97. os->clear(os->rdstate() & ~ios::failbit);
  98. switch( whence ) {
  99. case SEEK_SET:
  100. origin = data->myStreamStartPos;
  101. break;
  102. case SEEK_CUR:
  103. origin = os->tellp();
  104. break;
  105. case SEEK_END:
  106. os->seekp(0, ios::end);
  107. origin = os->tellp();
  108. break;
  109. }
  110. // restore original stream state
  111. os->clear(old_state);
  112. // only do something if desired seek position is valid
  113. if( origin + off > data->myStreamStartPos ) {
  114. toff_t num_fill;
  115. // clear the fail bit 
  116. os->clear(os->rdstate() & ~ios::failbit);
  117. // extend the stream to the expected size
  118. os->seekp(0, ios::end);
  119. num_fill = origin + off - (toff_t)os->tellp();
  120. for( toff_t i = 0; i < num_fill; i++ )
  121. os->put('');
  122. // retry the seek
  123. os->seekp(origin + off, ios::beg);
  124. }
  125. }
  126. return os->tellp();
  127. }
  128. static toff_t
  129. _tiffisSeekProc(thandle_t fd, toff_t off, int whence)
  130. {
  131. tiffis_data *data = (tiffis_data *)fd;
  132. switch(whence) {
  133. case SEEK_SET:
  134. data->myIS->seekg(data->myStreamStartPos + off, ios::beg);
  135. break;
  136. case SEEK_CUR:
  137. data->myIS->seekg(off, ios::cur);
  138. break;
  139. case SEEK_END:
  140. data->myIS->seekg(off, ios::end);
  141. break;
  142. }
  143. return ((long)data->myIS->tellg()) - data->myStreamStartPos;
  144. }
  145. static toff_t
  146. _tiffosSizeProc(thandle_t fd)
  147. {
  148. tiffos_data *data = (tiffos_data *)fd;
  149. ostream *os = data->myOS;
  150. toff_t pos = os->tellp();
  151. toff_t len;
  152. os->seekp(0, ios::end);
  153. len = os->tellp();
  154. os->seekp(pos);
  155. return len;
  156. }
  157. static toff_t
  158. _tiffisSizeProc(thandle_t fd)
  159. {
  160. tiffis_data *data = (tiffis_data *)fd;
  161. int pos = data->myIS->tellg();
  162. int len;
  163. data->myIS->seekg(0, ios::end);
  164. len = data->myIS->tellg();
  165. data->myIS->seekg(pos);
  166. return len;
  167. }
  168. static int
  169. _tiffosCloseProc(thandle_t fd)
  170. {
  171. // Our stream was not allocated by us, so it shouldn't be closed by us.
  172. delete (tiffos_data *)fd;
  173. return 0;
  174. }
  175. static int
  176. _tiffisCloseProc(thandle_t fd)
  177. {
  178. // Our stream was not allocated by us, so it shouldn't be closed by us.
  179. delete (tiffis_data *)fd;
  180. return 0;
  181. }
  182. static int
  183. _tiffDummyMapProc(thandle_t , tdata_t* , toff_t* )
  184. {
  185. return (0);
  186. }
  187. static void
  188. _tiffDummyUnmapProc(thandle_t , tdata_t , toff_t )
  189. {
  190. }
  191. /*
  192.  * Open a TIFF file descriptor for read/writing.
  193.  */
  194. static TIFF*
  195. _tiffStreamOpen(const char* name, const char* mode, void *fd)
  196. {
  197. TIFF* tif;
  198. if( strchr(mode, 'w') ) {
  199. tiffos_data *data = new tiffos_data;
  200. data->myOS = (ostream *)fd;
  201. data->myStreamStartPos = data->myOS->tellp();
  202. // Open for writing.
  203. tif = TIFFClientOpen(name, mode,
  204. (thandle_t) data,
  205. _tiffosReadProc, _tiffosWriteProc,
  206. _tiffosSeekProc, _tiffosCloseProc,
  207. _tiffosSizeProc,
  208. _tiffDummyMapProc, _tiffDummyUnmapProc);
  209. } else {
  210. tiffis_data *data = new tiffis_data;
  211. data->myIS = (istream *)fd;
  212. data->myStreamStartPos = data->myIS->tellg();
  213. // Open for reading.
  214. tif = TIFFClientOpen(name, mode,
  215. (thandle_t) data,
  216. _tiffisReadProc, _tiffisWriteProc,
  217. _tiffisSeekProc, _tiffisCloseProc,
  218. _tiffisSizeProc,
  219. _tiffDummyMapProc, _tiffDummyUnmapProc);
  220. }
  221. return (tif);
  222. }
  223. TIFF*
  224. TIFFStreamOpen(const char* name, ostream *os)
  225. {
  226. // If os is either a ostrstream or ostringstream, and has no data
  227. // written to it yet, then tellp() will return -1 which will break us.
  228. // We workaround this by writing out a dummy character and
  229. // then seek back to the beginning.
  230. if( !os->fail() && (int)os->tellp() < 0 ) {
  231. *os << '';
  232. os->seekp(0);
  233. }
  234. // NB: We don't support mapped files with streams so add 'm'
  235. return _tiffStreamOpen(name, "wm", os);
  236. }
  237. TIFF*
  238. TIFFStreamOpen(const char* name, istream *is)
  239. {
  240. // NB: We don't support mapped files with streams so add 'm'
  241. return _tiffStreamOpen(name, "rm", is);
  242. }
  243. /* vim: set ts=8 sts=8 sw=8 noet: */