4 * Written by Eryk Vershen
8 * Copyright 1997,1998 by Apple Computer, Inc.
11 * Permission to use, copy, modify, and distribute this software and
12 * its documentation for any purpose and without fee is hereby granted,
13 * provided that the above copyright notice appears in all copies and
14 * that both the copyright notice and this permission notice appear in
15 * supporting documentation.
17 * APPLE COMPUTER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
18 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
19 * FOR A PARTICULAR PURPOSE.
21 * IN NO EVENT SHALL APPLE COMPUTER BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
22 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
23 * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
24 * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
25 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
29 // for malloc() & free()
34 #include "deblock_media.h"
45 typedef struct deblock_media
*DEBLOCK_MEDIA
;
47 struct deblock_media
{
51 unsigned long next_block_size
;
52 unsigned char *buffer
;
55 struct deblock_globals
{
69 static long deblock_inited
= 0;
70 static struct deblock_globals deblock_info
;
73 * Forward declarations
75 void deblock_init(void);
76 DEBLOCK_MEDIA
new_deblock_media(void);
77 long read_deblock_media(MEDIA m
, long long offset
, unsigned long count
, void *address
);
78 long write_deblock_media(MEDIA m
, long long offset
, unsigned long count
, void *address
);
79 long close_deblock_media(MEDIA m
);
80 long os_reload_deblock_media(MEDIA m
);
89 if (deblock_inited
!= 0) {
94 deblock_info
.kind
= allocate_media_kind();
99 new_deblock_media(void)
101 return (DEBLOCK_MEDIA
) new_media(sizeof(struct deblock_media
));
106 open_deblock_media(unsigned long new_block_size
, MEDIA m
)
109 unsigned long block_size
;
111 if (deblock_inited
== 0) {
117 block_size
= media_granularity(m
);
119 if (new_block_size
== block_size
) {
122 } else if (new_block_size
> block_size
) {
123 if ((new_block_size
% block_size
) == 0) {
124 /* no filtering necessary */
125 a
= new_deblock_media();
127 a
->need_filtering
= 0;
128 a
->next_block_size
= block_size
;
132 /* too hard to bother with */
134 } else /* new_block_size < block_size */ {
135 if ((block_size
% new_block_size
) == 0) {
136 /* block & unblock */
137 a
= new_deblock_media();
139 a
->need_filtering
= 1;
140 a
->next_block_size
= block_size
;
141 a
->buffer
= malloc(block_size
);
144 /* too hard to bother with */
148 a
->m
.kind
= deblock_info
.kind
;
149 a
->m
.grain
= new_block_size
;
150 a
->m
.size_in_bytes
= media_total_size(m
);
151 a
->m
.do_read
= read_deblock_media
;
152 a
->m
.do_write
= write_deblock_media
;
153 a
->m
.do_close
= close_deblock_media
;
154 a
->m
.do_os_reload
= os_reload_deblock_media
;
163 read_deblock_media(MEDIA m
, long long offset
, unsigned long count
, void *address
)
167 unsigned long next_size
;
168 unsigned long partial_offset
;
169 unsigned long partial_count
;
170 long long cur_offset
;
171 unsigned long remainder
;
174 a
= (DEBLOCK_MEDIA
) m
;
178 } else if (a
->m
.kind
!= deblock_info
.kind
) {
179 /* wrong kind - XXX need to error here - this is an internal problem */
180 } else if (count
<= 0 || count
% a
->m
.grain
!= 0) {
181 /* can't handle size */
182 } else if (offset
< 0 || offset
% a
->m
.grain
!= 0) {
183 /* can't handle offset */
184 } else if (a
->need_filtering
== 0) {
185 rtn_value
= read_media(a
->next_media
, offset
, count
, address
);
187 next_size
= a
->next_block_size
;
194 partial_offset
= cur_offset
% next_size
;
195 if (partial_offset
!= 0) {
196 partial_count
= next_size
- partial_offset
;
197 if (partial_count
> remainder
) {
198 partial_count
= remainder
;
200 rtn_value
= read_media(a
->next_media
, cur_offset
- partial_offset
, next_size
, a
->buffer
);
201 if (rtn_value
!= 0) {
202 memcpy (addr
, a
->buffer
+ partial_offset
, partial_count
);
203 addr
+= partial_count
;
204 cur_offset
+= partial_count
;
205 remainder
-= partial_count
;
208 /* read fulls as long as needed */
209 if (rtn_value
!= 0 && remainder
> next_size
) {
210 partial_count
= remainder
- (remainder
% next_size
);
211 rtn_value
= read_media(a
->next_media
, cur_offset
, partial_count
, addr
);
212 addr
+= partial_count
;
213 cur_offset
+= partial_count
;
214 remainder
-= partial_count
;
217 if (rtn_value
!= 0 && remainder
> 0) {
218 partial_count
= remainder
;
219 rtn_value
= read_media(a
->next_media
, cur_offset
, next_size
, a
->buffer
);
220 if (rtn_value
!= 0) {
221 memcpy (addr
, a
->buffer
, partial_count
);
230 write_deblock_media(MEDIA m
, long long offset
, unsigned long count
, void *address
)
234 unsigned long next_size
;
235 unsigned long partial_offset
;
236 unsigned long partial_count
;
237 long long cur_offset
;
238 unsigned long remainder
;
241 a
= (DEBLOCK_MEDIA
) m
;
245 } else if (a
->m
.kind
!= deblock_info
.kind
) {
246 /* wrong kind - XXX need to error here - this is an internal problem */
247 } else if (count
<= 0 || count
% a
->m
.grain
!= 0) {
248 /* can't handle size */
249 } else if (offset
< 0 || offset
% a
->m
.grain
!= 0) {
250 /* can't handle offset */
251 } else if (a
->need_filtering
== 0) {
252 rtn_value
= write_media(a
->next_media
, offset
, count
, address
);
254 next_size
= a
->next_block_size
;
261 partial_offset
= cur_offset
% next_size
;
262 if (partial_offset
!= 0) {
263 partial_count
= next_size
- partial_offset
;
264 if (partial_count
> remainder
) {
265 partial_count
= remainder
;
267 rtn_value
= read_media(a
->next_media
, cur_offset
- partial_offset
, next_size
, a
->buffer
);
268 if (rtn_value
!= 0) {
269 memcpy (a
->buffer
+ partial_offset
, addr
, partial_count
);
270 rtn_value
= write_media(a
->next_media
, cur_offset
- partial_offset
, next_size
, a
->buffer
);
271 addr
+= partial_count
;
272 cur_offset
+= partial_count
;
273 remainder
-= partial_count
;
276 /* write fulls as long as needed */
277 if (rtn_value
!= 0 && remainder
> next_size
) {
278 partial_count
= remainder
- (remainder
% next_size
);
279 rtn_value
= write_media(a
->next_media
, cur_offset
, partial_count
, addr
);
280 addr
+= partial_count
;
281 cur_offset
+= partial_count
;
282 remainder
-= partial_count
;
285 if (rtn_value
!= 0 && remainder
> 0) {
286 partial_count
= remainder
;
287 rtn_value
= read_media(a
->next_media
, cur_offset
, next_size
, a
->buffer
);
288 if (rtn_value
!= 0) {
289 memcpy (a
->buffer
, addr
, partial_count
);
290 rtn_value
= write_media(a
->next_media
, cur_offset
, next_size
, a
->buffer
);
294 /* recompute size to handle file media */
295 a
->m
.size_in_bytes
= media_total_size(a
->next_media
);
301 close_deblock_media(MEDIA m
)
305 a
= (DEBLOCK_MEDIA
) m
;
308 } else if (a
->m
.kind
!= deblock_info
.kind
) {
309 /* XXX need to error here - this is an internal problem */
313 close_media(a
->next_media
);
320 os_reload_deblock_media(MEDIA m
)
324 a
= (DEBLOCK_MEDIA
) m
;
327 } else if (a
->m
.kind
!= deblock_info
.kind
) {
328 /* XXX need to error here - this is an internal problem */
332 os_reload_media(a
->next_media
);