| File: | ./io/_ccv_io_bmp.inc |
| Warning: | line 41, column 12 File position of the stream might be 'indeterminate' after a failed operation. Can cause undefined behavior |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 1 | #include "ccv.h" | ||||
| 2 | #include "ccv_internal.h" | ||||
| 3 | #ifdef HAVE_LIBPNG1 | ||||
| 4 | #ifdef __APPLE__ | ||||
| 5 | #include "TargetConditionals.h" | ||||
| 6 | #if TARGET_OS_IPHONE | ||||
| 7 | // iOS | ||||
| 8 | #elif TARGET_IPHONE_SIMULATOR | ||||
| 9 | // iOS Simulator | ||||
| 10 | #elif TARGET_OS_MAC | ||||
| 11 | #include <zlib.h> | ||||
| 12 | #include <png.h> | ||||
| 13 | #else | ||||
| 14 | // Unsupported platform | ||||
| 15 | #endif | ||||
| 16 | #else | ||||
| 17 | #include <zlib.h> | ||||
| 18 | #include <png.h> | ||||
| 19 | #endif | ||||
| 20 | #include "io/_ccv_io_libpng.inc" | ||||
| 21 | #endif | ||||
| 22 | #ifdef HAVE_LIBJPEG1 | ||||
| 23 | #include <jpeglib.h> | ||||
| 24 | #include "io/_ccv_io_libjpeg.inc" | ||||
| 25 | #endif | ||||
| 26 | #if defined(__unix__1) || (defined(__APPLE__) && defined(__MACH__)) | ||||
| 27 | #include <sys/param.h> | ||||
| 28 | #endif | ||||
| 29 | #include "io/_ccv_io_bmp.inc" | ||||
| 30 | #include "io/_ccv_io_binary.inc" | ||||
| 31 | #include "io/_ccv_io_raw.inc" | ||||
| 32 | |||||
| 33 | static int _ccv_read_and_close_fd(FILE* fd, ccv_dense_matrix_t** x, int type) | ||||
| 34 | { | ||||
| 35 | int ctype = (type & 0xF00) ? CCV_8U | ((type & 0xF00) >> 8) : 0; | ||||
| 36 | if ((type & 0XFF) == CCV_IO_ANY_FILE) | ||||
| 37 | { | ||||
| 38 | unsigned char sig[8]; | ||||
| 39 | (void) fread(sig, 1, 8, fd); | ||||
| 40 | if (memcmp(sig, "\x89\x50\x4e\x47\xd\xa\x1a\xa", 8) == 0) | ||||
| 41 | type = CCV_IO_PNG_FILE; | ||||
| 42 | else if (memcmp(sig, "\xff\xd8\xff", 3) == 0) | ||||
| 43 | type = CCV_IO_JPEG_FILE; | ||||
| 44 | else if (memcmp(sig, "BM", 2) == 0) | ||||
| 45 | type = CCV_IO_BMP_FILE; | ||||
| 46 | else if (memcmp(sig, "CCVBINDM", 8) == 0) | ||||
| 47 | type = CCV_IO_BINARY_FILE; | ||||
| 48 | fseek(fd, 0, SEEK_SET0); | ||||
| 49 | } | ||||
| 50 | switch (type & 0XFF) | ||||
| 51 | { | ||||
| 52 | #ifdef HAVE_LIBJPEG1 | ||||
| 53 | case CCV_IO_JPEG_FILE: | ||||
| 54 | _ccv_read_jpeg_fd(fd, x, ctype); | ||||
| 55 | break; | ||||
| 56 | #endif | ||||
| 57 | #ifdef HAVE_LIBPNG1 | ||||
| 58 | case CCV_IO_PNG_FILE: | ||||
| 59 | _ccv_read_png_fd(fd, x, ctype); | ||||
| 60 | break; | ||||
| 61 | #endif | ||||
| 62 | case CCV_IO_BMP_FILE: | ||||
| 63 | _ccv_read_bmp_fd(fd, x, ctype); | ||||
| 64 | break; | ||||
| 65 | case CCV_IO_BINARY_FILE: | ||||
| 66 | _ccv_read_binary_fd(fd, x, ctype); | ||||
| 67 | } | ||||
| 68 | if (*x != 0) | ||||
| 69 | ccv_make_matrix_immutable(*x); | ||||
| 70 | if (type & CCV_IO_ANY_FILE) | ||||
| 71 | fclose(fd); | ||||
| 72 | return CCV_IO_FINAL; | ||||
| 73 | } | ||||
| 74 | |||||
| 75 | static int _ccv_read_raw(ccv_dense_matrix_t** x, void* data, int type, int rows, int cols, int scanline) | ||||
| 76 | { | ||||
| 77 | assert(rows > 0 && cols > 0 && scanline > 0)((void) sizeof ((rows > 0 && cols > 0 && scanline > 0) ? 1 : 0), __extension__ ({ if (rows > 0 && cols > 0 && scanline > 0) ; else __assert_fail ("rows > 0 && cols > 0 && scanline > 0" , "ccv_io.c", 77, __extension__ __PRETTY_FUNCTION__); })); | ||||
| 78 | if (type & CCV_IO_NO_COPY) | ||||
| 79 | { | ||||
| 80 | // there is no conversion that we can apply if it is NO_COPY mode | ||||
| 81 | // NO_COPY mode generate an "unreusable" matrix, which requires you to | ||||
| 82 | // manually release its data block (which is, in fact the same data | ||||
| 83 | // block you passed in) | ||||
| 84 | int ctype = CCV_8U | CCV_C1; | ||||
| 85 | switch (type & 0xFF) | ||||
| 86 | { | ||||
| 87 | case CCV_IO_RGB_RAW: | ||||
| 88 | case CCV_IO_BGR_RAW: | ||||
| 89 | ctype = CCV_8U | CCV_C3; | ||||
| 90 | break; | ||||
| 91 | case CCV_IO_RGBA_RAW: | ||||
| 92 | case CCV_IO_ARGB_RAW: | ||||
| 93 | case CCV_IO_BGRA_RAW: | ||||
| 94 | case CCV_IO_ABGR_RAW: | ||||
| 95 | ctype = CCV_8U | CCV_C4; | ||||
| 96 | break; | ||||
| 97 | case CCV_IO_GRAY_RAW: | ||||
| 98 | default: | ||||
| 99 | /* default one */ | ||||
| 100 | break; | ||||
| 101 | } | ||||
| 102 | *x = ccv_dense_matrix_new(rows, cols, ctype | CCV_NO_DATA_ALLOC, data, 0); | ||||
| 103 | (*x)->step = scanline; | ||||
| 104 | } else { | ||||
| 105 | switch (type & 0xFF) | ||||
| 106 | { | ||||
| 107 | case CCV_IO_RGB_RAW: | ||||
| 108 | _ccv_read_rgb_raw(x, data, type, rows, cols, scanline); | ||||
| 109 | break; | ||||
| 110 | case CCV_IO_RGBA_RAW: | ||||
| 111 | _ccv_read_rgba_raw(x, data, type, rows, cols, scanline); | ||||
| 112 | break; | ||||
| 113 | case CCV_IO_ARGB_RAW: | ||||
| 114 | _ccv_read_argb_raw(x, data, type, rows, cols, scanline); | ||||
| 115 | break; | ||||
| 116 | case CCV_IO_BGR_RAW: | ||||
| 117 | _ccv_read_bgr_raw(x, data, type, rows, cols, scanline); | ||||
| 118 | break; | ||||
| 119 | case CCV_IO_BGRA_RAW: | ||||
| 120 | _ccv_read_bgra_raw(x, data, type, rows, cols, scanline); | ||||
| 121 | break; | ||||
| 122 | case CCV_IO_ABGR_RAW: | ||||
| 123 | _ccv_read_abgr_raw(x, data, type, rows, cols, scanline); | ||||
| 124 | break; | ||||
| 125 | case CCV_IO_GRAY_RAW: | ||||
| 126 | _ccv_read_gray_raw(x, data, type, rows, cols, scanline); | ||||
| 127 | break; | ||||
| 128 | } | ||||
| 129 | } | ||||
| 130 | if (*x != 0) | ||||
| 131 | ccv_make_matrix_immutable(*x); | ||||
| 132 | return CCV_IO_FINAL; | ||||
| 133 | } | ||||
| 134 | |||||
| 135 | #if defined(__APPLE__) || defined(__OpenBSD__) || defined(__FreeBSD__) | ||||
| 136 | |||||
| 137 | typedef struct { | ||||
| 138 | char* buffer; | ||||
| 139 | off_t pos; | ||||
| 140 | size_t size; | ||||
| 141 | } ccv_io_mem_t; | ||||
| 142 | |||||
| 143 | static int readfn(void* context, char* buf, int size) | ||||
| 144 | { | ||||
| 145 | ccv_io_mem_t* mem = (ccv_io_mem_t*)context; | ||||
| 146 | if (size + mem->pos > mem->size) | ||||
| 147 | size = mem->size - mem->pos; | ||||
| 148 | memcpy(buf, mem->buffer + mem->pos, size); | ||||
| 149 | mem->pos += size; | ||||
| 150 | return size; | ||||
| 151 | } | ||||
| 152 | |||||
| 153 | static off_t seekfn(void* context, off_t off, int whence) | ||||
| 154 | { | ||||
| 155 | ccv_io_mem_t* mem = (ccv_io_mem_t*)context; | ||||
| 156 | off_t pos; | ||||
| 157 | switch (whence) | ||||
| 158 | { | ||||
| 159 | case SEEK_SET0: | ||||
| 160 | pos = off; | ||||
| 161 | break; | ||||
| 162 | case SEEK_CUR1: | ||||
| 163 | pos = mem->pos + off; | ||||
| 164 | break; | ||||
| 165 | case SEEK_END2: | ||||
| 166 | pos = mem->size + off; | ||||
| 167 | break; | ||||
| 168 | } | ||||
| 169 | if (pos >= mem->size) | ||||
| 170 | return -1; | ||||
| 171 | mem->pos = pos; | ||||
| 172 | return pos; | ||||
| 173 | } | ||||
| 174 | |||||
| 175 | static int writefn(void* context, const char* buf, int size) | ||||
| 176 | { | ||||
| 177 | ccv_io_mem_t* mem = (ccv_io_mem_t*)context; | ||||
| 178 | if (size + mem->pos > mem->size) | ||||
| 179 | return -1; | ||||
| 180 | memcpy(mem->buffer + mem->pos, buf, size); | ||||
| 181 | mem->pos += size; | ||||
| 182 | return size; | ||||
| 183 | } | ||||
| 184 | #endif | ||||
| 185 | |||||
| 186 | int ccv_read_impl(const void* in, ccv_dense_matrix_t** x, int type, int rows, int cols, int scanline) | ||||
| 187 | { | ||||
| 188 | FILE* fd = 0; | ||||
| 189 | if (type & CCV_IO_ANY_FILE) | ||||
| |||||
| 190 | { | ||||
| 191 | assert(rows == 0 && cols == 0 && scanline == 0)((void) sizeof ((rows == 0 && cols == 0 && scanline == 0) ? 1 : 0), __extension__ ({ if (rows == 0 && cols == 0 && scanline == 0) ; else __assert_fail ("rows == 0 && cols == 0 && scanline == 0" , "ccv_io.c", 191, __extension__ __PRETTY_FUNCTION__); })); | ||||
| 192 | fd = fopen((const char*)in, "rb"); | ||||
| 193 | if (!fd
| ||||
| 194 | return CCV_IO_ERROR; | ||||
| 195 | return _ccv_read_and_close_fd(fd, x, type); | ||||
| 196 | } else if (type & CCV_IO_ANY_STREAM) { | ||||
| 197 | assert(rows > 8 && cols == 0 && scanline == 0)((void) sizeof ((rows > 8 && cols == 0 && scanline == 0) ? 1 : 0), __extension__ ({ if (rows > 8 && cols == 0 && scanline == 0) ; else __assert_fail ("rows > 8 && cols == 0 && scanline == 0" , "ccv_io.c", 197, __extension__ __PRETTY_FUNCTION__); })); | ||||
| 198 | assert((type & 0xFF) != CCV_IO_DEFLATE_STREAM)((void) sizeof (((type & 0xFF) != CCV_IO_DEFLATE_STREAM) ? 1 : 0), __extension__ ({ if ((type & 0xFF) != CCV_IO_DEFLATE_STREAM ) ; else __assert_fail ("(type & 0xFF) != CCV_IO_DEFLATE_STREAM" , "ccv_io.c", 198, __extension__ __PRETTY_FUNCTION__); })); // deflate stream (compressed stream) is not supported yet | ||||
| 199 | #if _XOPEN_SOURCE >= 700 || _POSIX_C_SOURCE200809L >= 200809L || defined(__APPLE__) || defined(__OpenBSD__) || defined(__FreeBSD__) | ||||
| 200 | // this is only supported by glibc | ||||
| 201 | #if _XOPEN_SOURCE >= 700 || _POSIX_C_SOURCE200809L >= 200809L | ||||
| 202 | fd = fmemopen((void*)in, (size_t)rows, "rb"); | ||||
| 203 | #else | ||||
| 204 | ccv_io_mem_t mem = { | ||||
| 205 | .size = rows, | ||||
| 206 | .pos = 0, | ||||
| 207 | .buffer = (char*)in, | ||||
| 208 | }; | ||||
| 209 | fd = funopen(&mem, readfn, 0, seekfn, 0); | ||||
| 210 | #endif | ||||
| 211 | if (!fd) | ||||
| 212 | return CCV_IO_ERROR; | ||||
| 213 | // mimicking itself as a "file" | ||||
| 214 | type = (type & ~0x10) | 0x20; | ||||
| 215 | return _ccv_read_and_close_fd(fd, x, type); | ||||
| 216 | #endif | ||||
| 217 | } else if (type & CCV_IO_ANY_RAW) { | ||||
| 218 | return _ccv_read_raw(x, (void*)in /* it can be modifiable if it is NO_COPY mode */, type, rows, cols, scanline); | ||||
| 219 | } | ||||
| 220 | return CCV_IO_UNKNOWN; | ||||
| 221 | } | ||||
| 222 | |||||
| 223 | int ccv_write(ccv_dense_matrix_t* mat, char* const out, size_t* const len, int type, void* conf) | ||||
| 224 | { | ||||
| 225 | FILE* fd = 0; | ||||
| 226 | #if defined(__APPLE__) || defined(__OpenBSD__) || defined(__FreeBSD__) | ||||
| 227 | ccv_io_mem_t mem = {0}; | ||||
| 228 | #endif | ||||
| 229 | if (type & CCV_IO_ANY_FILE) | ||||
| 230 | { | ||||
| 231 | fd = fopen(out, "wb"); | ||||
| 232 | if (!fd) | ||||
| 233 | return CCV_IO_ERROR; | ||||
| 234 | } else if ((type & CCV_IO_ANY_STREAM) && type != CCV_IO_PLAIN_STREAM) { | ||||
| 235 | assert(len)((void) sizeof ((len) ? 1 : 0), __extension__ ({ if (len) ; else __assert_fail ("len", "ccv_io.c", 235, __extension__ __PRETTY_FUNCTION__ ); })); | ||||
| 236 | assert((type & 0xFF) != CCV_IO_DEFLATE_STREAM)((void) sizeof (((type & 0xFF) != CCV_IO_DEFLATE_STREAM) ? 1 : 0), __extension__ ({ if ((type & 0xFF) != CCV_IO_DEFLATE_STREAM ) ; else __assert_fail ("(type & 0xFF) != CCV_IO_DEFLATE_STREAM" , "ccv_io.c", 236, __extension__ __PRETTY_FUNCTION__); })); // deflate stream (compressed stream) is not supported yet | ||||
| 237 | #if _XOPEN_SOURCE >= 700 || _POSIX_C_SOURCE200809L >= 200809L || defined(__APPLE__) || defined(__OpenBSD__) || defined(__FreeBSD__) | ||||
| 238 | // this is only supported by glibc | ||||
| 239 | #if _XOPEN_SOURCE >= 700 || _POSIX_C_SOURCE200809L >= 200809L | ||||
| 240 | fd = fmemopen((void*)out, *len, "wb"); | ||||
| 241 | #else | ||||
| 242 | mem.size = *len; | ||||
| 243 | mem.buffer = out; | ||||
| 244 | fd = funopen(&mem, 0, writefn, seekfn, 0); | ||||
| 245 | #endif | ||||
| 246 | #endif | ||||
| 247 | } | ||||
| 248 | int err = 0; | ||||
| 249 | switch (type) | ||||
| 250 | { | ||||
| 251 | case CCV_IO_JPEG_FILE: | ||||
| 252 | #ifdef HAVE_LIBJPEG1 | ||||
| 253 | err = _ccv_write_jpeg_fd(mat, fd, conf); | ||||
| 254 | if (len != 0) | ||||
| 255 | *len = 0; | ||||
| 256 | #else | ||||
| 257 | assert(0 && "ccv_write requires libjpeg support for JPEG format")((void) sizeof ((0 && "ccv_write requires libjpeg support for JPEG format" ) ? 1 : 0), __extension__ ({ if (0 && "ccv_write requires libjpeg support for JPEG format" ) ; else __assert_fail ("0 && \"ccv_write requires libjpeg support for JPEG format\"" , "ccv_io.c", 257, __extension__ __PRETTY_FUNCTION__); })); | ||||
| 258 | #endif | ||||
| 259 | break; | ||||
| 260 | case CCV_IO_PNG_FILE: | ||||
| 261 | #ifdef HAVE_LIBPNG1 | ||||
| 262 | err = _ccv_write_png_fd(mat, fd, conf); | ||||
| 263 | if (len != 0) | ||||
| 264 | *len = 0; | ||||
| 265 | #else | ||||
| 266 | assert(0 && "ccv_write requires libpng support for PNG format")((void) sizeof ((0 && "ccv_write requires libpng support for PNG format" ) ? 1 : 0), __extension__ ({ if (0 && "ccv_write requires libpng support for PNG format" ) ; else __assert_fail ("0 && \"ccv_write requires libpng support for PNG format\"" , "ccv_io.c", 266, __extension__ __PRETTY_FUNCTION__); })); | ||||
| 267 | #endif | ||||
| 268 | break; | ||||
| 269 | case CCV_IO_BINARY_FILE: | ||||
| 270 | _ccv_write_binary_fd(mat, fd, conf); | ||||
| 271 | if (len != 0) | ||||
| 272 | *len = 0; | ||||
| 273 | break; | ||||
| 274 | case CCV_IO_JPEG_STREAM: | ||||
| 275 | #ifdef HAVE_LIBJPEG1 | ||||
| 276 | err = _ccv_write_jpeg_fd(mat, fd, conf); | ||||
| 277 | #else | ||||
| 278 | assert(0 && "ccv_write requires libjpeg support for JPEG format")((void) sizeof ((0 && "ccv_write requires libjpeg support for JPEG format" ) ? 1 : 0), __extension__ ({ if (0 && "ccv_write requires libjpeg support for JPEG format" ) ; else __assert_fail ("0 && \"ccv_write requires libjpeg support for JPEG format\"" , "ccv_io.c", 278, __extension__ __PRETTY_FUNCTION__); })); | ||||
| 279 | #endif | ||||
| 280 | break; | ||||
| 281 | case CCV_IO_PNG_STREAM: | ||||
| 282 | #ifdef HAVE_LIBPNG1 | ||||
| 283 | err = _ccv_write_png_fd(mat, fd, conf); | ||||
| 284 | #else | ||||
| 285 | assert(0 && "ccv_write requires libpng support for PNG format")((void) sizeof ((0 && "ccv_write requires libpng support for PNG format" ) ? 1 : 0), __extension__ ({ if (0 && "ccv_write requires libpng support for PNG format" ) ; else __assert_fail ("0 && \"ccv_write requires libpng support for PNG format\"" , "ccv_io.c", 285, __extension__ __PRETTY_FUNCTION__); })); | ||||
| 286 | #endif | ||||
| 287 | break; | ||||
| 288 | case CCV_IO_PLAIN_STREAM: | ||||
| 289 | err = _ccv_write_plain_stream(mat, out, *len); | ||||
| 290 | *len = 20 + mat->step * mat->rows; | ||||
| 291 | break; | ||||
| 292 | } | ||||
| 293 | if ((type & CCV_IO_ANY_STREAM) && type != CCV_IO_PLAIN_STREAM) | ||||
| 294 | *len = (size_t)ftell(fd); | ||||
| 295 | if (fd) | ||||
| 296 | fclose(fd); | ||||
| 297 | return err != 0 ? CCV_IO_ERROR : CCV_IO_FINAL; | ||||
| 298 | } |
| 1 | static void _ccv_read_bmp_fd(FILE* in, ccv_dense_matrix_t** x, int type) | |||
| 2 | { | |||
| 3 | fseek(in, 10, SEEK_SET0); | |||
| 4 | int offset; | |||
| 5 | (void) fread(&offset, 4, 1, in); | |||
| 6 | int size; | |||
| 7 | (void) fread(&size, 4, 1, in); | |||
| 8 | int width = 0, height = 0, bpp = 0, rle_code = 0, clrused = 0; | |||
| 9 | if (size >= 36) | |||
| 10 | { | |||
| 11 | (void) fread(&width, 4, 1, in); | |||
| 12 | (void) fread(&height, 4, 1, in); | |||
| 13 | (void) fread(&bpp, 4, 1, in); | |||
| 14 | bpp = bpp >> 16; | |||
| 15 | (void) fread(&rle_code, 4, 1, in); | |||
| 16 | fseek(in, 12, SEEK_CUR1); | |||
| 17 | (void) fread(&clrused, 4, 1, in); | |||
| 18 | fseek(in, size - 36, SEEK_CUR1); | |||
| 19 | /* only support 24-bit bmp */ | |||
| 20 | } else if (size == 12) { | |||
| 21 | (void) fread(&width, 4, 1, in); | |||
| 22 | (void) fread(&height, 4, 1, in); | |||
| 23 | (void) fread(&bpp, 4, 1, in); | |||
| 24 | bpp = bpp >> 16; | |||
| 25 | /* TODO: not finished */ | |||
| 26 | } | |||
| 27 | if (width == 0 || height == 0 || bpp == 0) | |||
| 28 | return; | |||
| 29 | ccv_dense_matrix_t* im = *x; | |||
| 30 | if (im == 0) | |||
| 31 | *x = im = ccv_dense_matrix_new(height, width, (type) ? type : CCV_8U | ((bpp > 8) ? CCV_C3 : CCV_C1), 0, 0); | |||
| 32 | fseek(in, offset, SEEK_SET0); | |||
| 33 | int i, j; | |||
| 34 | unsigned char* ptr = im->data.u8 + (im->rows - 1) * im->step; | |||
| 35 | if ((bpp == 8 && CCV_GET_CHANNEL(im->type)((im->type) & 0xFFF) == CCV_C1) || (bpp == 24 && CCV_GET_CHANNEL(im->type)((im->type) & 0xFFF) == CCV_C3)) | |||
| 36 | { | |||
| 37 | if (CCV_GET_CHANNEL(im->type)((im->type) & 0xFFF) == CCV_C1) | |||
| 38 | { | |||
| 39 | for (i = 0; i < im->rows; i++) | |||
| 40 | { | |||
| 41 | (void) fread(ptr, 1, im->step, in); | |||
| ||||
| 42 | ptr -= im->step; | |||
| 43 | } | |||
| 44 | } else { | |||
| 45 | for (i = 0; i < im->rows; i++) | |||
| 46 | { | |||
| 47 | (void) fread(ptr, 1, im->step, in); | |||
| 48 | for (j = 0; j < im->cols * 3; j += 3) | |||
| 49 | { | |||
| 50 | unsigned char t = ptr[j]; | |||
| 51 | ptr[j] = ptr[j + 2]; | |||
| 52 | ptr[j + 2] = t; | |||
| 53 | } | |||
| 54 | ptr -= im->step; | |||
| 55 | } | |||
| 56 | } | |||
| 57 | } else { | |||
| 58 | if (bpp == 24 && CCV_GET_CHANNEL(im->type)((im->type) & 0xFFF) == CCV_C1) | |||
| 59 | { | |||
| 60 | int bufstep = (im->cols * 3 + 3) & -4; | |||
| 61 | unsigned char* buffer = (unsigned char*)alloca(bufstep)__builtin_alloca (bufstep); | |||
| 62 | for (i = 0; i < im->rows; i++) | |||
| 63 | { | |||
| 64 | (void) fread(buffer, 1, bufstep, in); | |||
| 65 | unsigned char* rgb = buffer; | |||
| 66 | unsigned char* g = ptr; | |||
| 67 | for(j = 0; j < im->cols; j++, rgb += 3, g++) | |||
| 68 | *g = (unsigned char)((rgb[2] * 6969 + rgb[1] * 23434 + rgb[0] * 2365) >> 15); | |||
| 69 | ptr -= im->step; | |||
| 70 | } | |||
| 71 | } else if (bpp == 8 && CCV_GET_CHANNEL(im->type)((im->type) & 0xFFF) == CCV_C3) { | |||
| 72 | int bufstep = (im->cols + 3) & -4; | |||
| 73 | unsigned char* buffer = (unsigned char*)alloca(bufstep)__builtin_alloca (bufstep); | |||
| 74 | for (i = 0; i < im->rows; i++) | |||
| 75 | { | |||
| 76 | (void) fread(buffer, 1, bufstep, in); | |||
| 77 | unsigned char* g = buffer; | |||
| 78 | unsigned char* rgb = ptr; | |||
| 79 | for(j = 0; j < im->cols; j++, rgb += 3, g++) | |||
| 80 | rgb[2] = rgb[1] = rgb[0] = *g; | |||
| 81 | ptr -= im->step; | |||
| 82 | } | |||
| 83 | } | |||
| 84 | } | |||
| 85 | } |