comparison src/video/SDL_renderer_sw.c @ 1918:092bd3a019c5

Starting on the OpenGL renderer...
author Sam Lantinga <slouken@libsdl.org>
date Wed, 19 Jul 2006 07:18:45 +0000
parents 06c27a737b7a
children 8a162bfdc838
comparison
equal deleted inserted replaced
1917:3f54b3ec5a07 1918:092bd3a019c5
28 #include "SDL_yuv_sw_c.h" 28 #include "SDL_yuv_sw_c.h"
29 29
30 30
31 /* SDL surface based renderer implementation */ 31 /* SDL surface based renderer implementation */
32 32
33 static SDL_Renderer *SDL_SW_CreateRenderer(SDL_Window * window, Uint32 flags); 33 static SDL_Renderer *SW_CreateRenderer(SDL_Window * window, Uint32 flags);
34 static int SDL_SW_CreateTexture(SDL_Renderer * renderer, 34 static int SW_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture);
35 SDL_Texture * texture); 35 static int SW_QueryTexturePixels(SDL_Renderer * renderer,
36 static int SDL_SW_QueryTexturePixels(SDL_Renderer * renderer, 36 SDL_Texture * texture, void **pixels,
37 SDL_Texture * texture, void **pixels, 37 int *pitch);
38 int *pitch); 38 static int SW_SetTexturePalette(SDL_Renderer * renderer,
39 static int SDL_SW_SetTexturePalette(SDL_Renderer * renderer, 39 SDL_Texture * texture,
40 SDL_Texture * texture, 40 const SDL_Color * colors, int firstcolor,
41 const SDL_Color * colors, int firstcolor, 41 int ncolors);
42 int ncolors); 42 static int SW_GetTexturePalette(SDL_Renderer * renderer,
43 static int SDL_SW_GetTexturePalette(SDL_Renderer * renderer, 43 SDL_Texture * texture, SDL_Color * colors,
44 SDL_Texture * texture, SDL_Color * colors, 44 int firstcolor, int ncolors);
45 int firstcolor, int ncolors); 45 static int SW_UpdateTexture(SDL_Renderer * renderer,
46 static int SDL_SW_UpdateTexture(SDL_Renderer * renderer, 46 SDL_Texture * texture, const SDL_Rect * rect,
47 SDL_Texture * texture, const SDL_Rect * rect, 47 const void *pixels, int pitch);
48 const void *pixels, int pitch); 48 static int SW_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
49 static int SDL_SW_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, 49 const SDL_Rect * rect, int markDirty,
50 const SDL_Rect * rect, int markDirty, 50 void **pixels, int *pitch);
51 void **pixels, int *pitch); 51 static void SW_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture);
52 static void SDL_SW_UnlockTexture(SDL_Renderer * renderer, 52 static void SW_DirtyTexture(SDL_Renderer * renderer,
53 SDL_Texture * texture); 53 SDL_Texture * texture, int numrects,
54 static void SDL_SW_DirtyTexture(SDL_Renderer * renderer, 54 const SDL_Rect * rects);
55 SDL_Texture * texture, int numrects, 55 static int SW_RenderFill(SDL_Renderer * renderer, const SDL_Rect * rect,
56 const SDL_Rect * rects); 56 Uint32 color);
57 static int SDL_SW_RenderFill(SDL_Renderer * renderer, const SDL_Rect * rect, 57 static int SW_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
58 Uint32 color); 58 const SDL_Rect * srcrect,
59 static int SDL_SW_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, 59 const SDL_Rect * dstrect, int blendMode,
60 const SDL_Rect * srcrect, 60 int scaleMode);
61 const SDL_Rect * dstrect, int blendMode, 61 static void SW_RenderPresent(SDL_Renderer * renderer);
62 int scaleMode); 62 static void SW_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture);
63 static void SDL_SW_RenderPresent(SDL_Renderer * renderer); 63 static void SW_DestroyRenderer(SDL_Renderer * renderer);
64 static void SDL_SW_DestroyTexture(SDL_Renderer * renderer, 64
65 SDL_Texture * texture); 65
66 static void SDL_SW_DestroyRenderer(SDL_Renderer * renderer); 66 SDL_RenderDriver SW_RenderDriver = {
67 67 SW_CreateRenderer,
68
69 SDL_RenderDriver SDL_SW_RenderDriver = {
70 SDL_SW_CreateRenderer,
71 { 68 {
72 "software", 69 "software",
73 (SDL_Renderer_SingleBuffer | SDL_Renderer_PresentCopy | 70 (SDL_Renderer_SingleBuffer | SDL_Renderer_PresentCopy |
74 SDL_Renderer_PresentFlip2 | SDL_Renderer_PresentFlip3 | 71 SDL_Renderer_PresentFlip2 | SDL_Renderer_PresentFlip3 |
75 SDL_Renderer_PresentDiscard | SDL_Renderer_PresentVSync), 72 SDL_Renderer_PresentDiscard | SDL_Renderer_PresentVSync),
99 int current_texture; 96 int current_texture;
100 SDL_Texture *texture[3]; 97 SDL_Texture *texture[3];
101 SDL_Surface surface; 98 SDL_Surface surface;
102 SDL_Renderer *renderer; 99 SDL_Renderer *renderer;
103 SDL_DirtyRectList dirty; 100 SDL_DirtyRectList dirty;
104 } SDL_SW_RenderData; 101 } SW_RenderData;
105 102
106 static SDL_Texture * 103 static SDL_Texture *
107 CreateTexture(SDL_Renderer * renderer, Uint32 format, int w, int h) 104 CreateTexture(SDL_Renderer * renderer, Uint32 format, int w, int h)
108 { 105 {
109 SDL_Texture *texture; 106 SDL_Texture *texture;
136 } 133 }
137 134
138 static int 135 static int
139 DisplayPaletteChanged(void *userdata, SDL_Palette * palette) 136 DisplayPaletteChanged(void *userdata, SDL_Palette * palette)
140 { 137 {
141 SDL_SW_RenderData *data = (SDL_SW_RenderData *) userdata; 138 SW_RenderData *data = (SW_RenderData *) userdata;
142 int i; 139 int i;
143 140
144 for (i = 0; i < SDL_arraysize(data->texture); ++i) { 141 for (i = 0; i < SDL_arraysize(data->texture); ++i) {
145 if (data->texture[i] && data->renderer->SetTexturePalette) { 142 if (data->texture[i] && data->renderer->SetTexturePalette) {
146 data->renderer->SetTexturePalette(data->renderer, 143 data->renderer->SetTexturePalette(data->renderer,
151 } 148 }
152 return 0; 149 return 0;
153 } 150 }
154 151
155 SDL_Renderer * 152 SDL_Renderer *
156 SDL_SW_CreateRenderer(SDL_Window * window, Uint32 flags) 153 SW_CreateRenderer(SDL_Window * window, Uint32 flags)
157 { 154 {
158 SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window); 155 SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window);
159 SDL_DisplayMode *displayMode = &display->current_mode; 156 SDL_DisplayMode *displayMode = &display->current_mode;
160 SDL_Renderer *renderer; 157 SDL_Renderer *renderer;
161 SDL_SW_RenderData *data; 158 SW_RenderData *data;
162 int i, n; 159 int i, n;
163 int bpp; 160 int bpp;
164 Uint32 Rmask, Gmask, Bmask, Amask; 161 Uint32 Rmask, Gmask, Bmask, Amask;
165 Uint32 renderer_flags; 162 Uint32 renderer_flags;
166 163
174 if (!renderer) { 171 if (!renderer) {
175 SDL_OutOfMemory(); 172 SDL_OutOfMemory();
176 return NULL; 173 return NULL;
177 } 174 }
178 175
179 data = (SDL_SW_RenderData *) SDL_malloc(sizeof(*data)); 176 data = (SW_RenderData *) SDL_malloc(sizeof(*data));
180 if (!data) { 177 if (!data) {
181 SDL_SW_DestroyRenderer(renderer); 178 SW_DestroyRenderer(renderer);
182 SDL_OutOfMemory(); 179 SDL_OutOfMemory();
183 return NULL; 180 return NULL;
184 } 181 }
185 SDL_zerop(data); 182 SDL_zerop(data);
186 183
187 renderer->CreateTexture = SDL_SW_CreateTexture; 184 renderer->CreateTexture = SW_CreateTexture;
188 renderer->QueryTexturePixels = SDL_SW_QueryTexturePixels; 185 renderer->QueryTexturePixels = SW_QueryTexturePixels;
189 renderer->SetTexturePalette = SDL_SW_SetTexturePalette; 186 renderer->SetTexturePalette = SW_SetTexturePalette;
190 renderer->GetTexturePalette = SDL_SW_GetTexturePalette; 187 renderer->GetTexturePalette = SW_GetTexturePalette;
191 renderer->UpdateTexture = SDL_SW_UpdateTexture; 188 renderer->UpdateTexture = SW_UpdateTexture;
192 renderer->LockTexture = SDL_SW_LockTexture; 189 renderer->LockTexture = SW_LockTexture;
193 renderer->UnlockTexture = SDL_SW_UnlockTexture; 190 renderer->UnlockTexture = SW_UnlockTexture;
194 renderer->DirtyTexture = SDL_SW_DirtyTexture; 191 renderer->DirtyTexture = SW_DirtyTexture;
195 renderer->RenderFill = SDL_SW_RenderFill; 192 renderer->RenderFill = SW_RenderFill;
196 renderer->RenderCopy = SDL_SW_RenderCopy; 193 renderer->RenderCopy = SW_RenderCopy;
197 renderer->RenderPresent = SDL_SW_RenderPresent; 194 renderer->RenderPresent = SW_RenderPresent;
198 renderer->DestroyTexture = SDL_SW_DestroyTexture; 195 renderer->DestroyTexture = SW_DestroyTexture;
199 renderer->DestroyRenderer = SDL_SW_DestroyRenderer; 196 renderer->DestroyRenderer = SW_DestroyRenderer;
200 renderer->info = SDL_SW_RenderDriver.info; 197 renderer->info = SW_RenderDriver.info;
201 renderer->window = window->id; 198 renderer->window = window->id;
202 renderer->driverdata = data; 199 renderer->driverdata = data;
203 200
204 renderer->info.flags = 0; 201 renderer->info.flags = 0;
205 202
221 if (flags & SDL_Renderer_PresentVSync) { 218 if (flags & SDL_Renderer_PresentVSync) {
222 renderer_flags |= SDL_Renderer_PresentVSync; 219 renderer_flags |= SDL_Renderer_PresentVSync;
223 } 220 }
224 for (i = 0; i < display->num_render_drivers; ++i) { 221 for (i = 0; i < display->num_render_drivers; ++i) {
225 SDL_RenderDriver *driver = &display->render_drivers[i]; 222 SDL_RenderDriver *driver = &display->render_drivers[i];
226 if (driver->info.name != SDL_SW_RenderDriver.info.name) { 223 if (driver->info.name != SW_RenderDriver.info.name) {
227 data->renderer = driver->CreateRenderer(window, renderer_flags); 224 data->renderer = driver->CreateRenderer(window, renderer_flags);
228 if (data->renderer) { 225 if (data->renderer) {
229 break; 226 break;
230 } 227 }
231 } 228 }
232 } 229 }
233 if (i == display->num_render_drivers) { 230 if (i == display->num_render_drivers) {
234 SDL_SW_DestroyRenderer(renderer); 231 SW_DestroyRenderer(renderer);
235 SDL_SetError("Couldn't find display render driver"); 232 SDL_SetError("Couldn't find display render driver");
236 return NULL; 233 return NULL;
237 } 234 }
238 if (data->renderer->info.flags & SDL_Renderer_PresentVSync) { 235 if (data->renderer->info.flags & SDL_Renderer_PresentVSync) {
239 renderer->info.flags |= SDL_Renderer_PresentVSync; 236 renderer->info.flags |= SDL_Renderer_PresentVSync;
242 /* Create the textures we'll use for display */ 239 /* Create the textures we'll use for display */
243 for (i = 0; i < n; ++i) { 240 for (i = 0; i < n; ++i) {
244 data->texture[i] = 241 data->texture[i] =
245 CreateTexture(data->renderer, data->format, window->w, window->h); 242 CreateTexture(data->renderer, data->format, window->w, window->h);
246 if (!data->texture[i]) { 243 if (!data->texture[i]) {
247 SDL_SW_DestroyRenderer(renderer); 244 SW_DestroyRenderer(renderer);
248 return NULL; 245 return NULL;
249 } 246 }
250 } 247 }
251 data->current_texture = 0; 248 data->current_texture = 0;
252 249
253 /* Create a surface we'll use for rendering */ 250 /* Create a surface we'll use for rendering */
254 data->surface.flags = SDL_PREALLOC; 251 data->surface.flags = SDL_PREALLOC;
255 data->surface.format = SDL_AllocFormat(bpp, Rmask, Gmask, Bmask, Amask); 252 data->surface.format = SDL_AllocFormat(bpp, Rmask, Gmask, Bmask, Amask);
256 if (!data->surface.format) { 253 if (!data->surface.format) {
257 SDL_SW_DestroyRenderer(renderer); 254 SW_DestroyRenderer(renderer);
258 return NULL; 255 return NULL;
259 } 256 }
260 SDL_SetSurfacePalette(&data->surface, display->palette); 257 SDL_SetSurfacePalette(&data->surface, display->palette);
261 258
262 /* Set up a palette watch on the display palette */ 259 /* Set up a palette watch on the display palette */
266 263
267 return renderer; 264 return renderer;
268 } 265 }
269 266
270 static int 267 static int
271 SDL_SW_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) 268 SW_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
272 { 269 {
273 if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) { 270 if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) {
274 texture->driverdata = SDL_SW_CreateYUVTexture(texture); 271 texture->driverdata = SDL_SW_CreateYUVTexture(texture);
275 } else { 272 } else {
276 int bpp; 273 int bpp;
292 } 289 }
293 return 0; 290 return 0;
294 } 291 }
295 292
296 static int 293 static int
297 SDL_SW_QueryTexturePixels(SDL_Renderer * renderer, SDL_Texture * texture, 294 SW_QueryTexturePixels(SDL_Renderer * renderer, SDL_Texture * texture,
298 void **pixels, int *pitch) 295 void **pixels, int *pitch)
299 { 296 {
300 if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) { 297 if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) {
301 return SDL_SW_QueryYUVTexturePixels((SDL_SW_YUVTexture *) texture-> 298 return SDL_SW_QueryYUVTexturePixels((SDL_SW_YUVTexture *) texture->
302 driverdata, pixels, pitch); 299 driverdata, pixels, pitch);
303 } else { 300 } else {
308 return 0; 305 return 0;
309 } 306 }
310 } 307 }
311 308
312 static int 309 static int
313 SDL_SW_SetTexturePalette(SDL_Renderer * renderer, SDL_Texture * texture, 310 SW_SetTexturePalette(SDL_Renderer * renderer, SDL_Texture * texture,
314 const SDL_Color * colors, int firstcolor, 311 const SDL_Color * colors, int firstcolor, int ncolors)
315 int ncolors)
316 { 312 {
317 if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) { 313 if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) {
318 SDL_SetError("YUV textures don't have a palette"); 314 SDL_SetError("YUV textures don't have a palette");
319 return -1; 315 return -1;
320 } else { 316 } else {
324 firstcolor, ncolors); 320 firstcolor, ncolors);
325 } 321 }
326 } 322 }
327 323
328 static int 324 static int
329 SDL_SW_GetTexturePalette(SDL_Renderer * renderer, SDL_Texture * texture, 325 SW_GetTexturePalette(SDL_Renderer * renderer, SDL_Texture * texture,
330 SDL_Color * colors, int firstcolor, int ncolors) 326 SDL_Color * colors, int firstcolor, int ncolors)
331 { 327 {
332 if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) { 328 if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) {
333 SDL_SetError("YUV textures don't have a palette"); 329 SDL_SetError("YUV textures don't have a palette");
334 return -1; 330 return -1;
335 } else { 331 } else {
340 return 0; 336 return 0;
341 } 337 }
342 } 338 }
343 339
344 static int 340 static int
345 SDL_SW_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, 341 SW_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
346 const SDL_Rect * rect, const void *pixels, int pitch) 342 const SDL_Rect * rect, const void *pixels, int pitch)
347 { 343 {
348 if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) { 344 if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) {
349 return SDL_SW_UpdateYUVTexture((SDL_SW_YUVTexture *) texture-> 345 return SDL_SW_UpdateYUVTexture((SDL_SW_YUVTexture *) texture->
350 driverdata, rect, pixels, pitch); 346 driverdata, rect, pixels, pitch);
351 } else { 347 } else {
367 return 0; 363 return 0;
368 } 364 }
369 } 365 }
370 366
371 static int 367 static int
372 SDL_SW_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, 368 SW_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
373 const SDL_Rect * rect, int markDirty, void **pixels, 369 const SDL_Rect * rect, int markDirty, void **pixels,
374 int *pitch) 370 int *pitch)
375 { 371 {
376 if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) { 372 if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) {
377 return SDL_SW_LockYUVTexture((SDL_SW_YUVTexture *) texture-> 373 return SDL_SW_LockYUVTexture((SDL_SW_YUVTexture *) texture->
378 driverdata, rect, markDirty, pixels, 374 driverdata, rect, markDirty, pixels,
379 pitch); 375 pitch);
387 return 0; 383 return 0;
388 } 384 }
389 } 385 }
390 386
391 static void 387 static void
392 SDL_SW_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture) 388 SW_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture)
393 { 389 {
394 if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) { 390 if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) {
395 SDL_SW_UnlockYUVTexture((SDL_SW_YUVTexture *) texture->driverdata); 391 SDL_SW_UnlockYUVTexture((SDL_SW_YUVTexture *) texture->driverdata);
396 } 392 }
397 } 393 }
398 394
399 static void 395 static void
400 SDL_SW_DirtyTexture(SDL_Renderer * renderer, SDL_Texture * texture, 396 SW_DirtyTexture(SDL_Renderer * renderer, SDL_Texture * texture,
401 int numrects, const SDL_Rect * rects) 397 int numrects, const SDL_Rect * rects)
402 { 398 {
403 } 399 }
404 400
405 static int 401 static int
406 SDL_SW_RenderFill(SDL_Renderer * renderer, const SDL_Rect * rect, 402 SW_RenderFill(SDL_Renderer * renderer, const SDL_Rect * rect, Uint32 color)
407 Uint32 color) 403 {
408 { 404 SW_RenderData *data = (SW_RenderData *) renderer->driverdata;
409 SDL_SW_RenderData *data = (SDL_SW_RenderData *) renderer->driverdata;
410 Uint8 r, g, b, a; 405 Uint8 r, g, b, a;
411 void *pixels; 406 void *pixels;
412 int pitch; 407 int pitch;
413 SDL_Rect real_rect; 408 SDL_Rect real_rect;
414 int status; 409 int status;
441 data->texture[data->current_texture]); 436 data->texture[data->current_texture]);
442 return status; 437 return status;
443 } 438 }
444 439
445 static int 440 static int
446 SDL_SW_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, 441 SW_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
447 const SDL_Rect * srcrect, const SDL_Rect * dstrect, 442 const SDL_Rect * srcrect, const SDL_Rect * dstrect,
448 int blendMode, int scaleMode) 443 int blendMode, int scaleMode)
449 { 444 {
450 SDL_SW_RenderData *data = (SDL_SW_RenderData *) renderer->driverdata; 445 SW_RenderData *data = (SW_RenderData *) renderer->driverdata;
451 SDL_Window *window = SDL_GetWindowFromID(renderer->window); 446 SDL_Window *window = SDL_GetWindowFromID(renderer->window);
452 int status; 447 int status;
453 448
454 if (data->renderer->info.flags & SDL_Renderer_PresentCopy) { 449 if (data->renderer->info.flags & SDL_Renderer_PresentCopy) {
455 SDL_AddDirtyRect(&data->dirty, dstrect); 450 SDL_AddDirtyRect(&data->dirty, dstrect);
499 data->texture[data->current_texture]); 494 data->texture[data->current_texture]);
500 return status; 495 return status;
501 } 496 }
502 497
503 static void 498 static void
504 SDL_SW_RenderPresent(SDL_Renderer * renderer) 499 SW_RenderPresent(SDL_Renderer * renderer)
505 { 500 {
506 SDL_SW_RenderData *data = (SDL_SW_RenderData *) renderer->driverdata; 501 SW_RenderData *data = (SW_RenderData *) renderer->driverdata;
507 SDL_Texture *texture = data->texture[data->current_texture]; 502 SDL_Texture *texture = data->texture[data->current_texture];
508 503
509 /* Send the data to the display */ 504 /* Send the data to the display */
510 if (data->renderer->info.flags & SDL_Renderer_PresentCopy) { 505 if (data->renderer->info.flags & SDL_Renderer_PresentCopy) {
511 SDL_DirtyRect *dirty; 506 SDL_DirtyRect *dirty;
535 data->current_texture = (data->current_texture + 1) % 3; 530 data->current_texture = (data->current_texture + 1) % 3;
536 } 531 }
537 } 532 }
538 533
539 static void 534 static void
540 SDL_SW_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture) 535 SW_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture)
541 { 536 {
542 if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) { 537 if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) {
543 SDL_SW_DestroyYUVTexture((SDL_SW_YUVTexture *) texture->driverdata); 538 SDL_SW_DestroyYUVTexture((SDL_SW_YUVTexture *) texture->driverdata);
544 } else { 539 } else {
545 SDL_Surface *surface = (SDL_Surface *) texture->driverdata; 540 SDL_Surface *surface = (SDL_Surface *) texture->driverdata;
547 SDL_FreeSurface(surface); 542 SDL_FreeSurface(surface);
548 } 543 }
549 } 544 }
550 545
551 static void 546 static void
552 SDL_SW_DestroyRenderer(SDL_Renderer * renderer) 547 SW_DestroyRenderer(SDL_Renderer * renderer)
553 { 548 {
554 SDL_SW_RenderData *data = (SDL_SW_RenderData *) renderer->driverdata; 549 SW_RenderData *data = (SW_RenderData *) renderer->driverdata;
555 SDL_Window *window = SDL_GetWindowFromID(renderer->window); 550 SDL_Window *window = SDL_GetWindowFromID(renderer->window);
556 SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window); 551 SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window);
557 int i; 552 int i;
558 553
559 if (data) { 554 if (data) {