Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 182605
Collapse All | Expand All

(-)import/import_im.c (-224 / +220 lines)
Lines 1-32 Link Here
1
/*
1
/*
2
 *  import_im.c
2
 *  import_im.c
3
 *
3
 *
4
 *  Copyright (C) Thomas Östreich - June 2001
4
 *  Copyright (C) Thomas Oestreich - June 2001
5
 *  port to MagickWand API:
6
 *  Copyright (C) Francesco Romani - July 2007
5
 *
7
 *
6
 *  This file is part of transcode, a video stream processing tool
8
 *  This file is part of transcode, a video stream processing tool
7
 *      
9
 *
8
 *  transcode is free software; you can redistribute it and/or modify
10
 *  transcode is free software; you can redistribute it and/or modify
9
 *  it under the terms of the GNU General Public License as published by
11
 *  it under the terms of the GNU General Public License as published by
10
 *  the Free Software Foundation; either version 2, or (at your option)
12
 *  the Free Software Foundation; either version 2, or (at your option)
11
 *  any later version.
13
 *  any later version.
12
 *   
14
 *
13
 *  transcode is distributed in the hope that it will be useful,
15
 *  transcode is distributed in the hope that it will be useful,
14
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 *  GNU General Public License for more details.
18
 *  GNU General Public License for more details.
17
 *   
19
 *
18
 *  You should have received a copy of the GNU General Public License
20
 *  You should have received a copy of the GNU General Public License
19
 *  along with GNU Make; see the file COPYING.  If not, write to
21
 *  along with GNU Make; see the file COPYING.  If not, write to
20
 *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 
22
 *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
21
 *
23
 *
22
 */
24
 */
23
25
24
#define MOD_NAME    "import_im.so"
26
#define MOD_NAME    "import_im.so"
25
#define MOD_VERSION "v0.0.4 (2003-09-15)"
27
#define MOD_VERSION "v0.1.0 (2007-07-17)"
26
#define MOD_CODEC   "(video) RGB"
28
#define MOD_CODEC   "(video) RGB"
27
29
30
/* Note: because of ImageMagick bogosity, this must be included first, so
31
 * we can undefine the PACKAGE_* symbols it splats into our namespace */
32
#include <wand/MagickWand.h>
33
#undef PACKAGE_BUGREPORT
34
#undef PACKAGE_NAME
35
#undef PACKAGE_STRING
36
#undef PACKAGE_TARNAME
37
#undef PACKAGE_VERSION
38
28
#include "transcode.h"
39
#include "transcode.h"
29
40
41
#include <stdlib.h>
42
#include <stdio.h>
43
30
static int verbose_flag = TC_QUIET;
44
static int verbose_flag = TC_QUIET;
31
static int capability_flag = TC_CAP_RGB | TC_CAP_VID;
45
static int capability_flag = TC_CAP_RGB | TC_CAP_VID;
32
46
Lines 37-312 Link Here
37
#include <sys/types.h>
51
#include <sys/types.h>
38
#include <regex.h>
52
#include <regex.h>
39
53
40
/* transcode defines these as well as ImageMagick. */
41
#undef PACKAGE_NAME
42
#undef PACKAGE_TARNAME
43
#undef PACKAGE_VERSION
44
#undef PACKAGE_STRING
45
54
46
#include <magick/api.h>
55
static char *head = NULL, *tail = NULL;
56
static int first_frame = 0, last_frame = 0, current_frame = 0, pad = 0;
57
static int width = 0, height = 0;
58
static MagickWand *wand = NULL;
47
59
48
60
49
extern int errno;
61
static int TCHandleMagickError(MagickWand *wand)
62
{
63
    ExceptionType severity;
64
    const char *description = MagickGetException(wand, &severity);
65
66
    tc_log_error(MOD_NAME, "%s", description);
50
67
51
char
68
    MagickRelinquishMemory((void*)description);
52
    *head = NULL,
69
    return TC_IMPORT_ERROR;
53
    *tail = NULL;
70
}
54
71
55
int
56
    first_frame = 0,
57
    last_frame = 0,
58
    current_frame = 0,
59
    pad = 0;
60
72
61
  
73
/* ------------------------------------------------------------
62
/* ------------------------------------------------------------ 
63
 *
74
 *
64
 * open stream
75
 * open stream
65
 *
76
 *
66
 * ------------------------------------------------------------*/
77
 * ------------------------------------------------------------*/
67
78
79
80
/* I suspect we have a lot of potential memleaks in here -- FRomani */
68
MOD_open
81
MOD_open
69
{
82
{
70
  int
83
    int result, string_length;
71
    result,
84
    long sret;
72
    string_length;
85
    char *regex, *frame, *filename;
73
86
    char printfspec[20];
74
  long
87
    regex_t preg;
75
    sret;
88
    regmatch_t pmatch[4];
76
77
  char
78
      *regex,
79
      *frame,
80
      *filename;
81
82
  char
83
      printfspec[20];
84
85
  regex_t
86
        preg;
87
88
  regmatch_t
89
      pmatch[4];
90
91
  if(param->flag == TC_AUDIO) {
92
      return(TC_IMPORT_OK);
93
  }
94
95
  if(param->flag == TC_VIDEO) {
96
97
    param->fd = NULL;
98
89
99
    // get the frame name and range
90
    if (param->flag == TC_AUDIO) {
100
    regex = "\\(.\\+[-._]\\)\\?\\([0-9]\\+\\)\\([-._].\\+\\)\\?";
91
        return TC_IMPORT_OK;
101
    result = regcomp(&preg, regex, 0);
102
    if (result) {
103
        perror("ERROR:  Regex compile failed.\n");
104
        return(TC_IMPORT_ERROR);
105
    }
92
    }
106
93
107
    result = regexec(&preg, vob->video_in_file, 4, pmatch, 0);
94
    if (param->flag == TC_VIDEO) {
108
    if (result) {
95
        param->fd = NULL;
109
        fprintf(stderr, "Regex match failed: no image sequence\n");
110
	string_length = strlen(vob->video_in_file) + 1;
111
        if ((head = malloc(string_length)) == NULL) {
112
	    perror("filename head");
113
	    return(TC_IMPORT_ERROR);
114
	}
115
	strlcpy(head, vob->video_in_file, string_length);
116
        tail = malloc(1);
117
        tail[0] = 0;
118
        first_frame = -1;
119
        last_frame = 0x7fffffff;
120
    }
121
    else {
122
        // split the name into head, frame number, and tail
123
        string_length = pmatch[1].rm_eo - pmatch[1].rm_so + 1;
124
        if ((head = malloc(string_length)) == NULL) {
125
            perror("filename head");
126
            return(TC_IMPORT_ERROR);
127
        }
128
        strlcpy(head, vob->video_in_file, string_length);
129
96
130
        string_length = pmatch[2].rm_eo - pmatch[2].rm_so + 1;
97
        // get the frame name and range
131
        if ((frame = malloc(string_length)) == NULL) {
98
        regex = "\\(.\\+[-._]\\)\\?\\([0-9]\\+\\)\\([-._].\\+\\)\\?";
132
            perror("filename frame");
99
        result = regcomp(&preg, regex, 0);
133
            return(TC_IMPORT_ERROR);
100
        if (result) {
101
            tc_log_perror(MOD_NAME, "ERROR:  Regex compile failed.\n");
102
            return TC_IMPORT_ERROR;
134
        }
103
        }
135
        strlcpy(frame, vob->video_in_file + pmatch[2].rm_so, string_length);
136
104
137
        // If the frame number is padded with zeros, record how many digits 
105
        result = regexec(&preg, vob->video_in_file, 4, pmatch, 0);
138
        // are actually being used.
106
        if (result) {
139
        if (frame[0] == '0') {
107
            tc_log_warn(MOD_NAME, "Regex match failed: no image sequence");
140
            pad = pmatch[2].rm_eo - pmatch[2].rm_so;
108
            string_length = strlen(vob->video_in_file) + 1;
109
            head = tc_malloc(string_length);
110
            if (head == NULL) {
111
                tc_log_perror(MOD_NAME, "filename head");
112
                return TC_IMPORT_ERROR;
113
            }
114
            strlcpy(head, vob->video_in_file, string_length);
115
            tail = tc_malloc(1); /* URGH -- FRomani */
116
            tail[0] = 0;
117
            first_frame = -1;
118
            last_frame = 0x7fffffff;
119
        } else {
120
            // split the name into head, frame number, and tail
121
            string_length = pmatch[1].rm_eo - pmatch[1].rm_so + 1;
122
            head = tc_malloc(string_length);
123
            if (head == NULL) {
124
                tc_log_perror(MOD_NAME, "filename head");
125
                return TC_IMPORT_ERROR;
126
            }
127
            strlcpy(head, vob->video_in_file, string_length);
128
129
            string_length = pmatch[2].rm_eo - pmatch[2].rm_so + 1;
130
            frame = tc_malloc(string_length);
131
            if (frame == NULL) {
132
                tc_log_perror(MOD_NAME, "filename frame");
133
                return TC_IMPORT_ERROR;
134
            }
135
            strlcpy(frame, vob->video_in_file + pmatch[2].rm_so, string_length);
136
137
            // If the frame number is padded with zeros, record how many digits
138
            // are actually being used.
139
            if (frame[0] == '0') {
140
                pad = pmatch[2].rm_eo - pmatch[2].rm_so;
141
            }
142
            first_frame = atoi(frame);
143
144
            string_length = pmatch[3].rm_eo - pmatch[3].rm_so + 1;
145
            tail = tc_malloc(string_length);
146
            if (tail == NULL) {
147
                tc_log_perror(MOD_NAME, "filename tail");
148
                return TC_IMPORT_ERROR;
149
            }
150
            strlcpy(tail, vob->video_in_file + pmatch[3].rm_so, string_length);
151
152
            // find the last frame by trying to open files
153
            last_frame = first_frame;
154
            filename = tc_malloc(strlen(head) + pad + strlen(tail) + 1);
155
            /* why remalloc frame? */
156
            /* frame = malloc(pad + 1); */
157
            do {
158
                last_frame++;
159
                tc_snprintf(printfspec, sizeof(printfspec), "%%s%%0%dd%%s", pad);
160
                string_length = strlen(head) + pad + strlen(tail) + 1;
161
                sret = tc_snprintf(filename, string_length, printfspec, head,
162
                                   last_frame, tail);
163
                if (sret < 0)
164
                  return TC_IMPORT_ERROR;
165
            } while (close(open(filename, O_RDONLY)) != -1); /* URGH -- Fromani */
166
            last_frame--;
167
            tc_free(filename);
168
            tc_free(frame);
141
        }
169
        }
142
        first_frame = atoi(frame);
143
170
144
        string_length = pmatch[3].rm_eo - pmatch[3].rm_so + 1;
171
        current_frame = first_frame;
145
        if ((tail = malloc(string_length)) == NULL) {
146
            perror("filename tail");
147
            return(TC_IMPORT_ERROR);
148
        }
149
        strlcpy(tail, vob->video_in_file + pmatch[3].rm_so, string_length);
150
172
151
        // find the last frame by trying to open files
173
        width = vob->im_v_width;
152
        last_frame = first_frame; 
174
        height = vob->im_v_height;
153
        filename = malloc(strlen(head) + pad + strlen(tail) + 1);
154
        /* why remalloc frame? */
155
        /* frame = malloc(pad + 1); */
156
        do {
157
            last_frame++;
158
            snprintf(printfspec, sizeof(printfspec), "%%s%%0%dd%%s", pad);
159
            string_length = strlen(head) + pad + strlen(tail) + 1;
160
            sret = snprintf(filename, string_length, printfspec, head,
161
                                                      last_frame, tail);
162
            if (tc_test_string(__FILE__, __LINE__, string_length, sret, errno))
163
              return(TC_IMPORT_ERROR);
164
        } while (close(open(filename, O_RDONLY)) != -1); 
165
        last_frame--;
166
        free(filename);
167
        free(frame);
168
    }
169
175
170
    current_frame = first_frame;
176
        MagickWandGenesis();
177
        wand = NewMagickWand();
171
178
172
    // initialize ImageMagick
179
        if (wand == NULL) {
173
    InitializeMagick("");
180
            tc_log_error(MOD_NAME, "cannot create magick wand");
181
            return TC_IMPORT_ERROR;
182
        }
183
        MagickResetIterator(wand); /* this needs to be done once */
174
184
175
    return(TC_IMPORT_OK);
185
        return TC_IMPORT_OK;
176
  }
186
    }
177
187
178
  return(TC_IMPORT_ERROR);
188
    return TC_IMPORT_ERROR;
179
}
189
}
180
190
181
191
182
/* ------------------------------------------------------------ 
192
/* ------------------------------------------------------------
183
 *
193
 *
184
 * decode  stream
194
 * decode  stream
185
 *
195
 *
186
 * ------------------------------------------------------------*/
196
 * ------------------------------------------------------------*/
187
197
188
MOD_decode {
198
MOD_decode
189
199
{
190
    ExceptionInfo
200
    char *filename = NULL, *frame = NULL;
191
        exception_info;
201
    int string_length;
192
202
    MagickBooleanType status;
193
    ImageInfo
194
        *image_info;
195
203
196
    Image
204
    if (param->flag == TC_AUDIO) {
197
        *image;
205
        return TC_IMPORT_OK;
198
199
    PixelPacket
200
        *pixel_packet;
201
202
    char
203
        *filename = NULL,
204
        *frame = NULL,
205
        *framespec = NULL;
206
207
    int
208
        column,
209
        row,
210
        string_length;
211
212
213
    if (current_frame > last_frame)
214
        return(TC_IMPORT_ERROR);
215
216
    // build the filename for the current frame
217
    string_length = strlen(head) + pad + strlen(tail) + 1;
218
    filename = malloc(string_length);
219
    if (pad) {
220
        frame = malloc(pad+1);
221
        framespec = malloc(10);
222
        snprintf(framespec, 10, "%%0%dd", pad);
223
        snprintf(frame, pad+1, framespec, current_frame);
224
        free(framespec);
225
        frame[pad] = '\0';
226
    }
227
    else if (first_frame >= 0) {
228
        frame = malloc(10);
229
        snprintf(frame, 10, "%d", current_frame);
230
    }
206
    }
231
    strlcpy(filename, head, string_length);
232
    if (frame != NULL) {
233
        strlcat(filename, frame, string_length);
234
        free(frame);
235
        frame = NULL;
236
    }
237
    strlcat(filename, tail, string_length);
238
207
239
    // Have ImageMagick open the file and read in the image data.
208
    if (param->flag == TC_VIDEO) {
240
    GetExceptionInfo(&exception_info);
209
        if (current_frame > last_frame)
241
    image_info=CloneImageInfo((ImageInfo *) NULL);
210
            return TC_IMPORT_ERROR;
242
    (void) strlcpy(image_info->filename, filename, MaxTextExtent);
211
243
    image=ReadImage(image_info,&exception_info);
212
        // build the filename for the current frame
244
    if (image == (Image *) NULL) {
213
        string_length = strlen(head) + pad + strlen(tail) + 1;
245
        MagickError(exception_info.severity,
214
        filename = tc_malloc(string_length);
246
                    exception_info.reason,
215
        if (pad) {
247
                    exception_info.description);
216
            char framespec[10];
248
	// skip
217
            frame = tc_malloc(pad+1);
249
	return (TC_IMPORT_ERROR);
218
            tc_snprintf(framespec, 10, "%%0%dd", pad);
250
    }
219
            tc_snprintf(frame, pad+1, framespec, current_frame);
220
            frame[pad] = '\0';
221
        } else if (first_frame >= 0) {
222
            frame = tc_malloc(10);
223
            tc_snprintf(frame, 10, "%d", current_frame);
224
        }
225
        strlcpy(filename, head, string_length);
226
        if (frame != NULL) {
227
            strlcat(filename, frame, string_length);
228
            tc_free(frame);
229
            frame = NULL;
230
        }
231
        strlcat(filename, tail, string_length);
251
232
252
    /*
233
        ClearMagickWand(wand);
253
     * Copy the pixels into a buffer in RGB order
234
        /* 
254
     */
235
         * This avoids IM to buffer all read images.
255
    pixel_packet = GetImagePixels(image, 0, 0, image->columns, image->rows);
236
         * I'm quite sure that this can be done in a smarter way,
256
    for (row = 0; row < image->rows; row++) {
237
         * but I haven't yet figured out how. -- FRomani
257
        for (column = 0; column < image->columns; column++) {
238
         */
258
          /*
239
259
           * The bit-shift 8 in the following lines is to convert 
240
        status = MagickReadImage(wand, filename);
260
           * 16-bit-per-channel images that may be read by ImageMagick 
241
        if (status == MagickFalse) {
261
           * into the 8-bit-per-channel images that transcode uses.
242
            return TCHandleMagickError(wand);
262
           * The bit-shift is still valid for 8-bit-per-channel images 
263
           * because when ImageMagick handles 8-bit images it still uses 
264
           * unsigned shorts, but stores the same 8-bit value in both 
265
           * the low and high byte.
266
           */
267
          param->buffer[(row * image->columns + column) * 3 + 0] =
268
               (char) (pixel_packet[(image->rows - row - 1) * image->columns +
269
                                                            column].blue >> 8);
270
          param->buffer[(row * image->columns + column) * 3 + 1] =
271
               (char) (pixel_packet[(image->rows - row - 1) * image->columns +
272
                                                           column].green >> 8);
273
          param->buffer[(row * image->columns + column) * 3 + 2] =
274
               (char) (pixel_packet[(image->rows - row - 1) * image->columns +
275
                                                             column].red >> 8);
276
        }
243
        }
277
    }
278
244
279
    if (current_frame == first_frame)
245
        MagickSetLastIterator(wand);
280
        param->attributes |= TC_FRAME_IS_KEYFRAME;
246
247
        status =  MagickGetImagePixels(wand,
248
                                       0, 0, width, height,
249
                                       "RGB", CharPixel,
250
                                       param->buffer);
251
        /* param->size already set correctly by caller */
252
        if (status == MagickFalse) {
253
            return TCHandleMagickError(wand);
254
        }
281
255
282
    current_frame++;
256
        if (current_frame == first_frame)
257
            param->attributes |= TC_FRAME_IS_KEYFRAME;
283
258
284
    // How do we do this?  The next line is not right (segfaults)
259
        current_frame++;
285
    // I can't find a DestroyPixelPacket() method.
260
    
286
    //free(pixel_packet);
261
        tc_free(filename);
287
    DestroyImage(image);
288
    DestroyImageInfo(image_info);
289
    DestroyExceptionInfo(&exception_info);
290
    free(filename);
291
262
292
    return(TC_IMPORT_OK);
263
        return TC_IMPORT_OK;
264
    }
265
    return TC_IMPORT_ERROR;
293
}
266
}
294
267
295
/* ------------------------------------------------------------ 
268
/* ------------------------------------------------------------
296
 *
269
 *
297
 * close stream
270
 * close stream
298
 *
271
 *
299
 * ------------------------------------------------------------*/
272
 * ------------------------------------------------------------*/
300
273
301
MOD_close
274
MOD_close
302
{  
275
{
303
  if (param->fd != NULL) pclose(param->fd);
276
    if (param->flag == TC_AUDIO) {
304
  if (head != NULL) free(head);
277
        return TC_IMPORT_OK;
305
  if (tail != NULL) free(tail);
278
    }
306
307
  DestroyMagick();
308
279
309
  return(TC_IMPORT_OK);
280
    if (param->flag == TC_VIDEO) {
281
        if (param->fd != NULL)
282
            pclose(param->fd);
283
        if (head != NULL)
284
            tc_free(head);
285
        if (tail != NULL)
286
            tc_free(tail);
287
288
        if (wand != NULL) {
289
            DestroyMagickWand(wand);
290
            MagickWandTerminus();
291
            wand = NULL;
292
        }
293
        return TC_IMPORT_OK;
294
    }
295
    return TC_IMPORT_ERROR;
310
}
296
}
311
297
298
/*************************************************************************/
312
299
300
/*
301
 * Local variables:
302
 *   c-file-style: "stroustrup"
303
 *   c-file-offsets: ((case-label . *) (statement-case-intro . *))
304
 *   indent-tabs-mode: nil
305
 * End:
306
 *
307
 * vim: expandtab shiftwidth=4:
308
 */
(-)import/import_imlist.c (-125 / +133 lines)
Lines 1-59 Link Here
1
/*
1
/*
2
 *  import_imlist.c
2
 *  import_imlist.c
3
 *
3
 *
4
 *  Copyright (C) Thomas Östreich - February 2002
4
 *  Copyright (C) Thomas Oestreich - February 2002
5
 *  port to MagickWand API:
6
 *  Copyright (C) Francesco Romani - July 2007
5
 *
7
 *
6
 *  This file is part of transcode, a video stream processing tool
8
 *  This file is part of transcode, a video stream processing tool
7
 *      
9
 *
8
 *  transcode is free software; you can redistribute it and/or modify
10
 *  transcode is free software; you can redistribute it and/or modify
9
 *  it under the terms of the GNU General Public License as published by
11
 *  it under the terms of the GNU General Public License as published by
10
 *  the Free Software Foundation; either version 2, or (at your option)
12
 *  the Free Software Foundation; either version 2, or (at your option)
11
 *  any later version.
13
 *  any later version.
12
 *   
14
 *
13
 *  transcode is distributed in the hope that it will be useful,
15
 *  transcode is distributed in the hope that it will be useful,
14
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 *  GNU General Public License for more details.
18
 *  GNU General Public License for more details.
17
 *   
19
 *
18
 *  You should have received a copy of the GNU General Public License
20
 *  You should have received a copy of the GNU General Public License
19
 *  along with GNU Make; see the file COPYING.  If not, write to
21
 *  along with GNU Make; see the file COPYING.  If not, write to
20
 *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 
22
 *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
21
 *
23
 *
22
 */
24
 */
23
25
24
#define MOD_NAME    "import_imlist.so"
26
#define MOD_NAME    "import_imlist.so"
25
#define MOD_VERSION "v0.0.2 (2003-11-13)"
27
#define MOD_VERSION "v0.1.0 (2007-07-17)"
26
#define MOD_CODEC   "(video) RGB"
28
#define MOD_CODEC   "(video) RGB"
27
29
30
/* Note: because of ImageMagick bogosity, this must be included first, so
31
 * we can undefine the PACKAGE_* symbols it splats into our namespace */
32
#include <wand/MagickWand.h>
33
#undef PACKAGE_BUGREPORT
34
#undef PACKAGE_NAME
35
#undef PACKAGE_STRING
36
#undef PACKAGE_TARNAME
37
#undef PACKAGE_VERSION
38
28
#include "transcode.h"
39
#include "transcode.h"
29
40
41
#include <stdlib.h>
42
#include <stdio.h>
43
30
static int verbose_flag = TC_QUIET;
44
static int verbose_flag = TC_QUIET;
31
static int capability_flag = TC_CAP_RGB | TC_CAP_VID | TC_CAP_AUD;
45
static int capability_flag = TC_CAP_RGB|TC_CAP_VID;
32
46
33
#define MOD_PRE imlist
47
#define MOD_PRE imlist
34
#include "import_def.h"
48
#include "import_def.h"
35
49
36
50
37
// transcode defines this as well as ImageMagick.
51
static int TCHandleMagickError(MagickWand *wand)
38
#undef PACKAGE_NAME
52
{
39
#undef PACKAGE_TARNAME
53
    ExceptionType severity;
40
#undef PACKAGE_VERSION
54
    const char *description = MagickGetException(wand, &severity);
41
#undef PACKAGE_STRING
42
43
#include <magick/api.h>
44
55
56
    tc_log_error(MOD_NAME, "%s", description);
45
57
46
int
58
    MagickRelinquishMemory((void*)description);
47
    first_frame = 0,
59
    return TC_IMPORT_ERROR;
48
    last_frame = 0,
60
}
49
    current_frame = 0,
50
    pad = 0;
51
61
52
static FILE *fd; 
62
static int width = 0, height = 0;
53
static char buffer[PATH_MAX+2];
63
static FILE *fd = NULL;
54
  
64
static MagickWand *wand = NULL;
55
65
56
/* ------------------------------------------------------------ 
66
/* ------------------------------------------------------------
57
 *
67
 *
58
 * open stream
68
 * open stream
59
 *
69
 *
Lines 61-187 Link Here
61
71
62
MOD_open
72
MOD_open
63
{
73
{
64
  if(param->flag == TC_AUDIO) {
74
    if (param->flag == TC_AUDIO) {
65
      return(TC_IMPORT_OK);
75
        return(TC_IMPORT_OK);
66
  }
76
    }
67
  
77
68
  if(param->flag == TC_VIDEO) {
78
    if (param->flag == TC_VIDEO) {
69
79
        param->fd = NULL;
70
    param->fd = NULL;
80
71
81
        width  = vob->im_v_width;
72
    if((fd = fopen(vob->video_in_file, "r"))==NULL) return(TC_IMPORT_ERROR);
82
        height = vob->im_v_height;
73
    
83
74
    // initialize ImageMagick
84
        fd = fopen(vob->video_in_file, "r");
75
    InitializeMagick("");
85
        if (fd == NULL) {
76
86
            return TC_IMPORT_ERROR;
77
    return(TC_IMPORT_OK);
87
        }
78
  }
88
79
 
89
        MagickWandGenesis();
80
  return(TC_IMPORT_ERROR);
90
        wand = NewMagickWand();
91
92
        if (wand == NULL) {
93
            tc_log_error(MOD_NAME, "cannot create magick wand");
94
            return TC_IMPORT_ERROR;
95
        }
96
97
        return TC_IMPORT_OK;
98
    }
99
100
    return TC_IMPORT_ERROR;
81
}
101
}
82
102
83
103
84
/* ------------------------------------------------------------ 
104
/* ------------------------------------------------------------
85
 *
105
 *
86
 * decode  stream
106
 * decode  stream
87
 *
107
 *
88
 * ------------------------------------------------------------*/
108
 * ------------------------------------------------------------*/
89
109
90
MOD_decode {
110
MOD_decode
111
{
112
    char filename[PATH_MAX+1];
113
    MagickBooleanType status;
114
115
    if (param->flag == TC_AUDIO) {
116
        return TC_IMPORT_OK;
117
    }
118
119
    if (param->flag == TC_VIDEO) {
120
        // read a filename from the list
121
        if (fgets(filename, PATH_MAX, fd) == NULL) {
122
            return TC_IMPORT_ERROR;
123
        }
124
        filename[PATH_MAX] = '\0'; /* enforce */
125
126
        ClearMagickWand(wand);
127
        /* 
128
         * This avoids IM to buffer all read images.
129
         * I'm quite sure that this can be done in a smarter way,
130
         * but I haven't yet figured out how. -- FRomani
131
         */
132
133
        status = MagickReadImage(wand, filename);
134
        if (status == MagickFalse) {
135
            return TCHandleMagickError(wand);
136
        }
91
137
92
    ExceptionInfo
138
        MagickSetLastIterator(wand);
93
        exception_info;
94
139
95
    ImageInfo
140
        status = MagickGetImagePixels(wand,
96
        *image_info;
141
                                      0, 0, width, height,
142
                                      "RGB", CharPixel,
143
                                      param->buffer);
144
        if (status == MagickFalse) {
145
            return TCHandleMagickError(wand);
146
        }
97
147
98
    Image
148
        param->attributes |= TC_FRAME_IS_KEYFRAME;
99
        *image;
100
101
    PixelPacket
102
        *pixel_packet;
103
104
    char
105
        *filename = NULL;
106
107
    int
108
        column,
109
        row, n;
110
111
    if(param->flag == TC_AUDIO) return(TC_IMPORT_OK);
112
    
113
    // read a filename from the list
114
    if(fgets (buffer, PATH_MAX, fd)==NULL) return(TC_IMPORT_ERROR);    
115
    
116
    filename = buffer; 
117
118
    n=strlen(filename);
119
    if(n<2) return(TC_IMPORT_ERROR);  
120
    filename[n-1]='\0';
121
    
122
    // Have ImageMagick open the file and read in the image data.
123
    GetExceptionInfo(&exception_info);
124
    image_info=CloneImageInfo((ImageInfo *) NULL);
125
    (void) strlcpy(image_info->filename, filename, MaxTextExtent);
126
127
    image=ReadImage(image_info, &exception_info);
128
    if (image == (Image *) NULL) {
129
        MagickError(exception_info.severity, exception_info.reason,
130
                    exception_info.description);
131
	// skipping
132
	return TC_IMPORT_OK;
133
    }
134
135
    /*
136
     * Copy the pixels into a buffer in RGB order
137
     */
138
    pixel_packet = GetImagePixels(image, 0, 0, image->columns, image->rows);
139
    for (row = 0; row < image->rows; row++) {
140
        for (column = 0; column < image->columns; column++) {
141
          param->buffer[(row * image->columns + column) * 3 + 0] =
142
               pixel_packet[(image->rows - row - 1) * image->columns +
143
                                                                 column].blue;
144
          param->buffer[(row * image->columns + column) * 3 + 1] =
145
               pixel_packet[(image->rows - row - 1) * image->columns +
146
                                                                 column].green;
147
          param->buffer[(row * image->columns + column) * 3 + 2] =
148
               pixel_packet[(image->rows - row - 1) * image->columns +
149
                                                                 column].red;
150
        }
151
    }
152
153
    param->attributes |= TC_FRAME_IS_KEYFRAME;
154
155
    // How do we do this?  The next line is not right (segfaults)
156
    // I can't find a DestroyPixelPacket() method.
157
    //free(pixel_packet);
158
    DestroyImage(image);
159
    DestroyImageInfo(image_info);
160
    DestroyExceptionInfo(&exception_info);
161
149
162
    return(TC_IMPORT_OK);
150
        return TC_IMPORT_OK;
151
    }
152
    return TC_IMPORT_ERROR;
163
}
153
}
164
154
165
/* ------------------------------------------------------------ 
155
/* ------------------------------------------------------------
166
 *
156
 *
167
 * close stream
157
 * close stream
168
 *
158
 *
169
 * ------------------------------------------------------------*/
159
 * ------------------------------------------------------------*/
170
160
171
MOD_close
161
MOD_close
172
{  
162
{
163
    if (param->flag == TC_AUDIO) {
164
        return TC_IMPORT_OK;
165
    }
166
167
    if (param->flag == TC_VIDEO) {
168
        if (fd != NULL) {
169
            fclose(fd);
170
            fd = NULL;
171
        }
172
173
        if (wand != NULL) {
174
            DestroyMagickWand(wand);
175
            MagickWandTerminus();
176
            wand = NULL;
177
        }
173
178
174
  if(param->flag == TC_VIDEO) {
179
        return TC_IMPORT_OK;
175
    
180
    }
176
    if(fd != NULL) fclose(fd); fd = NULL;
181
177
182
    return TC_IMPORT_ERROR;
178
    // This is very necessary
179
    DestroyMagick();
180
181
    return(TC_IMPORT_OK);
182
  }
183
  
184
  if(param->flag == TC_AUDIO) return(TC_IMPORT_OK);
185
 
186
  return(TC_IMPORT_ERROR);
187
}
183
}
184
185
/*************************************************************************/
186
187
/*
188
 * Local variables:
189
 *   c-file-style: "stroustrup"
190
 *   c-file-offsets: ((case-label . *) (statement-case-intro . *))
191
 *   indent-tabs-mode: nil
192
 * End:
193
 *
194
 * vim: expandtab shiftwidth=4:
195
 */

Return to bug 182605