0001 function MakeQTMovie(cmd,arg, arg2)
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079 if nargin < 1
0080 fprintf('Syntax: MakeQTMovie cmd [arg]\n')
0081 fprintf('The following commands are supported:\n');
0082 fprintf(' addfigure - Add snapshot of current figure to movie\n')
0083 fprintf(' addaxes - Add snapshot of current axes to movie\n')
0084 fprintf(' addmatrix data - Add a matrix to movie ');
0085 fprintf('(convert to jpeg)\n')
0086 fprintf(' addmatrixsc data - Add a matrix to movie ');
0087 fprintf('(scale and convert to jpeg)\n')
0088 fprintf(' addsound data - Add sound samples ');
0089 fprintf('(with optional rate)\n')
0090 fprintf(' demo - Show this program in action\n');
0091 fprintf(' finish - Finish movie, write out QT file\n');
0092 fprintf(' framerate # - Set movie frame rate ');
0093 fprintf('(default is 10fps)\n');
0094 fprintf(' quality # - Set JPEG quality (between 0 and 1)\n');
0095 fprintf(' size [# #] - Set plot size to [width height]\n');
0096 fprintf(' start filename - Start making a movie with ');
0097 fprintf('this name\n');
0098 return;
0099 end
0100
0101 global MakeQTMovieStatus
0102 MakeDefaultQTMovieStatus;
0103
0104 if(~isfield(MakeQTMovieStatus,'imageTmp'))
0105 MakeQTMovieStatus.imageTmp='tmp.jpg';
0106 end
0107
0108 switch lower(cmd)
0109 case {'addframe','addplot','addfigure','addaxes'}
0110 switch lower(cmd)
0111 case {'addframe','addfigure'}
0112 hObj = gcf;
0113 otherwise
0114 hObj = gca;
0115 end
0116 frame = getframe(hObj);
0117 [I,map] = frame2im(frame);
0118 if ImageSizeChanged(size(I)) > 0
0119 return;
0120 end
0121 if isempty(map)
0122
0123 imwrite(I,MakeQTMovieStatus.imageTmp, 'jpg', 'Quality', ...
0124 MakeQTMovieStatus.spatialQual*100);
0125 else
0126
0127 writejpg_map(MakeQTMovieStatus.imageTmp, I, map);
0128 end
0129 [pos, len] = AddFileToMovie;
0130 if(~isfield(MakeQTMovieStatus,'frameNumber'))
0131 MakeQTMovieStatus.frameNumber=0;
0132 end
0133 n = MakeQTMovieStatus.frameNumber + 1;
0134 MakeQTMovieStatus.frameNumber = n;
0135 MakeQTMovieStatus.frameStarts(n) = pos;
0136 MakeQTMovieStatus.frameLengths(n) = len;
0137
0138
0139
0140
0141
0142 case 'addimage'
0143 if nargin < 2
0144 fprintf('MakeQTMovie error: Need to specify a filename with ');
0145 fprintf('the image command.\n');
0146 return;
0147 end
0148
0149
0150
0151
0152 tim = imread(arg); tim_size = size(tim);
0153
0154 fprintf('Image %s size %d %d\n', arg, tim_size(1), tim_size(2));
0155 if ImageSizeChanged(tim_size) > 0
0156 return;
0157 end
0158 [pos, len] = AddFileToMovie(arg);
0159 n = MakeQTMovieStatus.frameNumber + 1;
0160 MakeQTMovieStatus.frameNumber = n;
0161 MakeQTMovieStatus.frameStarts(n) = pos;
0162 MakeQTMovieStatus.frameLengths(n) = len;
0163
0164 case 'addmatrix'
0165 if nargin < 2
0166 fprintf('MakeQTMovie error: Need to specify a matrix with ');
0167 fprintf('the addmatrix command.\n');
0168 return;
0169 end
0170 if ImageSizeChanged(size(arg)) > 0
0171 return;
0172 end
0173
0174
0175
0176
0177
0178 if ndims(arg) < 3
0179 arg(:,:,2) = arg;
0180 arg(:,:,3) = arg(:,:,1);
0181 end
0182 imwrite(arg, MakeQTMovieStatus.imageTmp, 'jpg', 'Quality', ...
0183 MakeQTMovieStatus.spatialQual*100);
0184 [pos, len] = AddFileToMovie;
0185 n = MakeQTMovieStatus.frameNumber + 1;
0186 MakeQTMovieStatus.frameNumber = n;
0187 MakeQTMovieStatus.frameStarts(n) = pos;
0188 MakeQTMovieStatus.frameLengths(n) = len;
0189
0190 case 'addmatrixsc'
0191 if nargin < 2
0192 fprintf('MakeQTMovie error: Need to specify a matrix with ');
0193 fprintf('the addmatrix command.\n');
0194 return;
0195 end
0196 if ImageSizeChanged(size(arg)) > 0
0197 return;
0198 end
0199 arg = arg - min(min(arg));
0200 arg = arg / max(max(arg));
0201
0202
0203
0204
0205
0206 if ndims(arg) < 3
0207 arg(:,:,2) = arg;
0208 arg(:,:,3) = arg(:,:,1);
0209 end
0210 imwrite(arg, MakeQTMovieStatus.imageTmp, 'jpg', 'Quality', ...
0211 MakeQTMovieStatus.spatialQual*100);
0212 [pos, len] = AddFileToMovie;
0213 n = MakeQTMovieStatus.frameNumber + 1;
0214 MakeQTMovieStatus.frameNumber = n;
0215 MakeQTMovieStatus.frameStarts(n) = pos;
0216 MakeQTMovieStatus.frameLengths(n) = len;
0217
0218 case 'addsound'
0219 if nargin < 2
0220 fprintf('MakeQTMovie error: Need to specify a sound array ');
0221 fprintf('with the addsound command.\n');
0222 return;
0223 end
0224
0225 OpenMovieFile
0226 MakeQTMovieStatus.soundLength = length(arg);
0227 arg = round(arg/max(max(abs(arg)))*32765);
0228 negs = find(arg<0);
0229 arg(negs) = arg(negs) + 65536;
0230
0231 sound = mb16(arg);
0232 MakeQTMovieStatus.soundStart = ftell(MakeQTMovieStatus.movieFp);
0233 MakeQTMovieStatus.soundLen = length(sound);
0234 fwrite(MakeQTMovieStatus.movieFp, sound, 'uchar');
0235 if nargin < 3
0236 arg2 = 22050;
0237 end
0238 MakeQTMovieStatus.soundRate = arg2;
0239
0240 case 'cleanup'
0241 if isstruct(MakeQTMovieStatus)
0242 if(isfield(MakeQTMovieStatus,'moveFp')),
0243 if ~isempty(MakeQTMovieStatus.movieFp)
0244 fclose(MakeQTMovieStatus.movieFp);
0245 MakeQTMovieStatus.movieFp = [];
0246 end
0247 else
0248 MakeQTMovieStatus.movieFp=[];
0249 end
0250
0251 if(isfield(MakeQTMovieStatus,'imageTmp'))
0252 if ~isempty(MakeQTMovieStatus.imageTmp) & ...
0253 exist(MakeQTMovieStatus.imageTmp,'file') > 0
0254 delete(MakeQTMovieStatus.imageTmp);
0255 MakeQTMovieStatus.imageTmp = [];
0256 end
0257 else
0258 MakeQTMovieStatus.imageTmp=[];
0259 end
0260 end
0261 MakeQTMovieStatus = [];
0262
0263 case 'debug'
0264 fprintf('Current Movie Data:\n');
0265 fprintf(' %d frames at %d fps\n', MakeQTMovieStatus.frameNumber, ...
0266 MakeQTMovieStatus.frameRate);
0267 starts = MakeQTMovieStatus.frameStarts;
0268 if length(starts) > 10, starts = starts(1:10);, end;
0269 lens = MakeQTMovieStatus.frameLengths;
0270 if length(lens) > 10, lens = lens(1:10);, end;
0271 fprintf(' Start: %6d Size: %6d\n', [starts; lens]);
0272 fprintf(' Movie Image Size: %dx%d\n', ...
0273 MakeQTMovieStatus.imageSize(2), ...
0274 MakeQTMovieStatus.imageSize(1));
0275 if length(MakeQTMovieStatus.soundStart) > 0
0276 fprintf(' Sound: %d samples at %d Hz sampling rate ', ...
0277 MakeQTMovieStatus.soundLength, ...
0278 MakeQTMovieStatus.soundRate);
0279 fprintf('at %d.\n', MakeQTMovieStatus.soundStart);
0280 else
0281 fprintf(' Sound: No sound track\n');
0282 end
0283 fprintf(' Temporary files for images: %s\n', ...
0284 MakeQTMovieStatus.imageTmp);
0285 fprintf(' Final movie name: %s\n', MakeQTMovieStatus.movieName);
0286 fprintf(' Compression Quality: %g\n', ...
0287 MakeQTMovieStatus.spatialQual);
0288
0289
0290 case 'demo'
0291 clf
0292 fps = 10;
0293 movieLength = 10;
0294 sr = 22050;
0295 fn = 'test.mov';
0296 fprintf('Creating the movie %s.\n', fn);
0297 MakeQTMovie('start',fn);
0298 MakeQTMovie('size', [160 120]);
0299 MakeQTMovie('quality', 1.0);
0300 theSound = [];
0301 for i=1:movieLength
0302 plot(sin((1:100)/4+i));
0303 MakeQTMovie('addaxes');
0304 theSound = [theSound sin(440/sr*2*pi*(2^(i/12))*(1:sr/fps))];
0305 end
0306 MakeQTMovie('framerate', fps);
0307 MakeQTMovie('addsound', theSound, sr);
0308 MakeQTMovie('finish');
0309
0310 case {'finish','close'}
0311 AddQTHeader;
0312 MakeQTMovie('cleanup')
0313
0314 case 'framerate'
0315 if nargin < 2
0316 fprintf('MakeQTMovie error: Need to specify the ');
0317 fprintf('frames/second with the framerate command.\n');
0318 return;
0319 end
0320 MakeQTMovieStatus.frameRate = arg;
0321
0322 case 'help'
0323 MakeQTMovie
0324
0325 case 'size'
0326
0327
0328 if nargin < 2
0329 fprintf('MakeQTMovie error: Need to specify a vector with ');
0330 fprintf('the size command.\n');
0331 return;
0332 end
0333 if length(arg) ~= 2
0334 error('MakeQTMovie: Error, must supply 2 element size.');
0335 end
0336 oldUnits = get(gcf,'units');
0337 set(gcf,'units','pixels');
0338 cursize = get(gcf, 'position');
0339 cursize(3) = arg(1);
0340 cursize(4) = arg(2);
0341 set(gcf, 'position', cursize);
0342 set(gcf,'units',oldUnits);
0343
0344 case 'start'
0345 if nargin < 2
0346 fprintf('MakeQTMovie error: Need to specify a file name ');
0347 fprintf('with start command.\n');
0348 return;
0349 end
0350 MakeQTMovie('cleanup');
0351 MakeDefaultQTMovieStatus;
0352 MakeQTMovieStatus.movieName = arg;
0353
0354 case 'test'
0355 clf
0356 MakeQTMovieStatus = [];
0357 MakeQTMovie('start','test.mov');
0358 MakeQTMovie('size', [320 240]);
0359 MakeQTMovie('quality', 1.0);
0360 subplot(2,2,1);
0361 for i=1:10
0362 plot(sin((1:100)/4+i));
0363 MakeQTMovie('addfigure');
0364 end
0365 MakeQTMovie('framerate', 10);
0366 MakeQTMovie('addsound', sin(1:5000), 22050);
0367 MakeQTMovie('debug');
0368 MakeQTMovie('finish');
0369
0370 case 'quality'
0371 if nargin < 2
0372 fprintf('MakeQTMovie error: Need to specify a quality ');
0373 fprintf('(between 0-1) with the quality command.\n');
0374 return;
0375 end
0376 MakeQTMovieStatus.spatialQual = arg;
0377
0378 otherwise
0379 fprintf('MakeQTMovie: Unknown method %s.\n', cmd);
0380 end
0381
0382
0383
0384 function MakeDefaultQTMovieStatus
0385 global MakeQTMovieStatus
0386 if isempty(MakeQTMovieStatus)
0387 MakeQTMovieStatus = struct(...
0388 'frameRate', 10, ...
0389 'frameStarts', [], ...
0390 'frameLengths', [], ...
0391 'timeScale', 10, ...
0392 'soundRate', 22050, ...
0393 'soundStart', [], ...
0394 'soundLength', 0, ...
0395 'soundChannels', 1, ...
0396 'frameNumber', 0, ...
0397 'movieFp', [], ...
0398 'imageTmp', tempname, ...
0399 'movieName', 'output.mov', ...
0400 'imageSize', [0 0], ...
0401 'trackNumber', 0, ...
0402 'timeScaleExpansion', 100, ...
0403 'spatialQual', 1.0);
0404 end
0405
0406
0407
0408
0409
0410 function err = ImageSizeChanged(newsize)
0411 global MakeQTMovieStatus
0412
0413 newsize = newsize(1:2);
0414 if(isfield(MakeQTMovieStatus,'imageSize'))
0415 oldsize = MakeQTMovieStatus.imageSize;
0416 else
0417 oldsize=newsize;
0418 MakeQTMovieStatus.imageSize=oldsize;
0419 end
0420 err = 0;
0421
0422 if sum(oldsize) == 0
0423 MakeQTMovieStatus.imageSize = newsize;
0424 else
0425 if sum(newsize ~= oldsize) > 0
0426 fprintf('MakeQTMovie Error: New image size');
0427 fprintf('(%dx%d) doesn''t match old size (%dx%d)\n', ...
0428 newsize(1), newsize(2), oldsize(1), oldsize(2));
0429 fprintf(' Can''t add this image to the movie.\n');
0430 err = 1;
0431 end
0432 end
0433
0434
0435
0436
0437
0438
0439
0440 function [pos, len] = AddFileToMovie(imageTmp)
0441 global MakeQTMovieStatus
0442 OpenMovieFile
0443 if nargin < 1
0444 imageTmp = MakeQTMovieStatus.imageTmp;
0445 end
0446 fp = fopen(imageTmp, 'rb');
0447 if fp < 0
0448 error('Could not reopen QT image temporary file.');
0449 end
0450
0451 len = 0;
0452 pos = ftell(MakeQTMovieStatus.movieFp);
0453 while 1
0454 data = fread(fp, 1024*16, 'uchar');
0455 if isempty(data)
0456 break;
0457 end
0458 cnt = fwrite(MakeQTMovieStatus.movieFp, data, 'uchar');
0459 len = len + cnt;
0460 end
0461 fclose(fp);
0462
0463
0464
0465
0466
0467 function AddQTHeader()
0468 global MakeQTMovieStatus
0469
0470 pos = ftell(MakeQTMovieStatus.movieFp);
0471 header = moov_atom;
0472 cnt = fwrite(MakeQTMovieStatus.movieFp, header, 'uchar');
0473 fseek(MakeQTMovieStatus.movieFp, 0, -1);
0474 cnt = fwrite(MakeQTMovieStatus.movieFp, mb32(pos), 'uchar');
0475 fclose(MakeQTMovieStatus.movieFp);
0476 MakeQTMovieStatus.movieFp = [];
0477
0478
0479
0480
0481 function OpenMovieFile
0482 global MakeQTMovieStatus
0483 if(isfield(MakeQTMovieStatus,'movieFp')),
0484 if isempty(MakeQTMovieStatus.movieFp)
0485 fp = fopen(MakeQTMovieStatus.movieName, 'wb');
0486 if fp < 0
0487 error('Could not open QT movie output file.');
0488 end
0489 MakeQTMovieStatus.movieFp = fp;
0490 cnt = fwrite(fp, [mb32(0) mbstring('mdat')], 'uchar');
0491 end
0492 else
0493 fp = fopen(MakeQTMovieStatus.movieName,'wb');
0494 if(fp<0)
0495 error('Could not open QT movie output file.');
0496 end
0497 MakeQTMovieStatus.movieFp=fp;
0498 cnt=fwrite(fp,[mb32(0) mbstring('mdat')], 'uchar');
0499 end
0500
0501
0502
0503
0504 function writejpg_map(name,I,map)
0505 global MakeQTMovieStatus
0506
0507 [y,x] = size(I);
0508
0509
0510
0511
0512 I = max(1,min(I,size(map,1)));
0513
0514 rgb = zeros(y, x, 3);
0515 t = zeros(y,x);
0516 t(:) = map(I(:),1)*255; rgb(:,:,1) = t;
0517 t(:) = map(I(:),2)*255; rgb(:,:,2) = t;
0518 t(:) = map(I(:),3)*255; rgb(:,:,3) = t;
0519
0520 imwrite(uint8(rgb),name,'jpeg','Quality',MakeQTMovieStatus.spatialQual*100);
0521
0522
0523
0524 function y=SetAtomSize(x)
0525 y = x;
0526 y(1:4) = mb32(length(x));
0527
0528
0529
0530 function y = mb32(x)
0531 if size(x,1) > size(x,2)
0532 x = x';
0533 end
0534
0535 y = [bitand(bitshift(x,-24),255); ...
0536 bitand(bitshift(x,-16),255); ...
0537 bitand(bitshift(x, -8),255); ...
0538 bitand(x, 255)];
0539 y = y(:)';
0540
0541
0542
0543 function y = mb16(x)
0544 if size(x,1) > size(x,2)
0545 x = x';
0546 end
0547
0548 y = [bitand(bitshift(x, -8),255); ...
0549 bitand(x, 255)];
0550 y = y(:)';
0551
0552
0553
0554 function y = mb8(x)
0555 if size(x,1) > size(x,2)
0556 x = x';
0557 end
0558
0559 y = [bitand(x, 255)];
0560 y = y(:)';
0561
0562
0563
0564
0565
0566
0567
0568
0569
0570
0571
0572 function y = mbstring(s)
0573 y = double(s);
0574
0575
0576
0577 function y = dinf_atom()
0578 y = SetAtomSize([mb32(0) mbstring('dinf') dref_atom]);
0579
0580
0581 function y = dref_atom()
0582 y = SetAtomSize([mb32(0) mbstring('dref') mb32(0) mb32(1) ...
0583 mb32(12) mbstring('alis') mb32(1)]);
0584
0585
0586 function y = edts_atom(add_sound_p)
0587 global MakeQTMovieStatus
0588 fixed1 = bitshift(1,16);
0589 if add_sound_p > 0
0590 duration = MakeQTMovieStatus.soundLength / ...
0591 MakeQTMovieStatus.soundRate * ...
0592 MakeQTMovieStatus.timeScale;
0593 else
0594 duration = MakeQTMovieStatus.frameNumber / ...
0595 MakeQTMovieStatus.frameRate * ...
0596 MakeQTMovieStatus.timeScale;
0597 end
0598 duration = ceil(duration);
0599
0600 y = [mb32(0) ...
0601 mbstring('edts') ...
0602 SetAtomSize([mb32(0) ...
0603 mbstring('elst') ...
0604 mb32(0) ...
0605 mb32(1) ...
0606 mb32(duration) ...
0607 mb32(0) ...
0608 mb32(fixed1)])];
0609 y = SetAtomSize(y);
0610
0611
0612 function y = hdlr_atom(component_type, sub_type)
0613 if strcmp(sub_type, 'vide')
0614 type_string = 'Apple Video Media Handler';
0615 elseif strcmp(sub_type, 'alis')
0616 type_string = 'Apple Alias Data Handler';
0617 elseif strcmp(sub_type, 'soun')
0618 type_string = 'Apple Sound Media Handler';
0619 end
0620
0621 y = [mb32(0) ...
0622 mbstring('hdlr') ...
0623 mb32(0) ...
0624 mbstring(component_type) ...
0625 mbstring(sub_type) ...
0626 mbstring('appl') ...
0627 mb32(0) ...
0628 mb32(0) ...
0629 mb8(length(type_string)) ...
0630 mbstring(type_string)];
0631 y = SetAtomSize(y);
0632
0633
0634 function y = mdhd_atom(add_sound_p)
0635 global MakeQTMovieStatus
0636
0637 if add_sound_p
0638 data = [mb32(MakeQTMovieStatus.soundRate) ...
0639 mb32(MakeQTMovieStatus.soundLength)];
0640 else
0641 data = [mb32(MakeQTMovieStatus.frameRate * ...
0642 MakeQTMovieStatus.timeScaleExpansion) ...
0643 mb32(MakeQTMovieStatus.frameNumber * ...
0644 MakeQTMovieStatus.timeScaleExpansion)];
0645 end
0646
0647 y = [mb32(0) mbstring('mdhd') ...
0648 mb32(0) ...
0649 mb32(round(now*3600*24)) ...
0650 mb32(round(now*3600*24)) ...
0651 data ...
0652 mb16(0) mb16(0)];
0653 y = SetAtomSize(y);
0654
0655
0656 function y = mdia_atom(add_sound_p)
0657 global MakeQTMovieStatus
0658
0659 if add_sound_p
0660 hdlr = hdlr_atom('mhlr', 'soun');
0661 else
0662 hdlr = hdlr_atom('mhlr', 'vide');
0663 end
0664
0665 y = [mb32(0) mbstring('mdia') ...
0666 mdhd_atom(add_sound_p) ...
0667 hdlr ...
0668 minf_atom(add_sound_p)];
0669 y = SetAtomSize(y);
0670
0671
0672
0673 function y = minf_atom(add_sound_p)
0674 global MakeQTMovieStatus
0675
0676 if add_sound_p
0677 data = smhd_atom;
0678 else
0679 data = vmhd_atom;
0680 end
0681
0682 y = [mb32(0) mbstring('minf') ...
0683 data ...
0684 hdlr_atom('dhlr','alis') ...
0685 dinf_atom ...
0686 stbl_atom(add_sound_p)];
0687 y = SetAtomSize(y);
0688
0689
0690 function y=moov_atom
0691 global MakeQTMovieStatus
0692 if(~isfield(MakeQTMovieStatus,'timeScaleExpansion'))
0693 MakeQTMovieStatus.timeScaleExpansion=100;
0694 end
0695 MakeQTMovieStatus.timeScale = MakeQTMovieStatus.frameRate * ...
0696 MakeQTMovieStatus.timeScaleExpansion;
0697
0698 if(~isfield(MakeQTMovieStatus,'soundLength'))
0699 MakeQTMovieStatus.soundLength=0;
0700 end
0701 if MakeQTMovieStatus.soundLength > 0
0702 sound = trak_atom(1);
0703 else
0704 sound = [];
0705 end
0706
0707 y = [mb32(0) mbstring('moov') ...
0708 mvhd_atom udat_atom sound trak_atom(0) ];
0709 y = SetAtomSize(y);
0710
0711
0712 function y=mvhd_atom
0713 global MakeQTMovieStatus
0714
0715 fixed1 = bitshift(1,16);
0716 frac1 = bitshift(1,30);
0717
0718 if(~isfield(MakeQTMovieStatus,'soundStart'))
0719 MakeQTMovieStatus.soundStart=0;
0720 end
0721
0722 if length(MakeQTMovieStatus.soundStart) > 0
0723 NumberOfTracks = 2;
0724 else
0725 NumberOfTracks = 1;
0726 end
0727
0728 if(~isfield(MakeQTMovieStatus,'soundRate'))
0729 MakeQTMovieStatus.soundRate=22050;
0730 end
0731
0732
0733
0734 MovieDuration = max(MakeQTMovieStatus.frameNumber / ...
0735 MakeQTMovieStatus.frameRate, ...
0736 MakeQTMovieStatus.soundLength / ...
0737 MakeQTMovieStatus.soundRate);
0738 MovieDuration = ceil(MovieDuration * MakeQTMovieStatus.timeScale);
0739
0740 y = [mb32(0) ...
0741 mbstring('mvhd') ...
0742 mb32(0) ...
0743 mb32(0) ...
0744 mb32(0) ...
0745 mb32(MakeQTMovieStatus.timeScale) ...
0746 mb32(MovieDuration) ...
0747 mb32(fixed1) ...
0748 mb16(255) ...
0749 mb16(0) ...
0750 mb32(0) ...
0751 mb32(0) ...
0752 mb32(fixed1) mb32(0) mb32(0) ...
0753 mb32(0) mb32(fixed1) mb32(0) ...
0754 mb32(0) mb32(0) mb32(frac1) ...
0755 mb32(0) ...
0756 mb32(0) ...
0757 mb32(0) ...
0758 mb32(0) ...
0759 mb32(0) ...
0760 mb32(0) ...
0761 mb32(NumberOfTracks)];
0762
0763 y = SetAtomSize(y);
0764
0765
0766 function y = raw_image_description()
0767 global MakeQTMovieStatus
0768
0769 fixed1 = bitshift(1,16);
0770 codec = [12 'Photo - JPEG '];
0771
0772 y = [mb32(0) mbstring('jpeg') ...
0773 mb32(0) mb16(0) mb16(0) mb16(0) mb16(1) ...
0774 mbstring('appl') ...
0775 mb32(1023) ...
0776 mb32(floor(1023*MakeQTMovieStatus.spatialQual)) ...
0777 mb16(MakeQTMovieStatus.imageSize(2)) ...
0778 mb16(MakeQTMovieStatus.imageSize(1)) ...
0779 mb32(fixed1 * 72) mb32(fixed1 * 72) ...
0780 mb32(0) ...
0781 mb16(0) ...
0782 mbstring(codec) ...
0783 mb16(24) mb16(65535)];
0784 y = SetAtomSize(y);
0785
0786
0787
0788 function y = raw_sound_description()
0789 global MakeQTMovieStatus
0790
0791 if(~isfield(MakeQTMovieStatus,'soundChannels'))
0792 MakeQTMovieStatus.soundChannels=1;
0793 end
0794
0795 y = [mb32(0) mbstring('twos') ...
0796 mb32(0) mb16(0) mb16(0) mb16(0) mb16(0) ...
0797 mb32(0) ...
0798 mb16(MakeQTMovieStatus.soundChannels) ...
0799 mb16(16) ...
0800 mb16(0) mb16(0) ...
0801 mb32(round(MakeQTMovieStatus.soundRate*65536))];
0802 y = SetAtomSize(y);
0803
0804
0805
0806 function y = smhd_atom()
0807 y = SetAtomSize([mb32(0) mbstring('smhd') mb32(0) mb16(0) mb16(0)]);
0808
0809
0810
0811
0812
0813 function y = stbl_atom(add_sound_p)
0814 y = [mb32(0) mbstring('stbl') ...
0815 stsd_atom(add_sound_p) ...
0816 stts_atom(add_sound_p) ...
0817 stsc_atom(add_sound_p) ...
0818 stsz_atom(add_sound_p) ...
0819 stco_atom(add_sound_p)];
0820 y = SetAtomSize(y);
0821
0822
0823 function y = stco_atom(add_sound_p)
0824 global MakeQTMovieStatus
0825 if add_sound_p
0826 y = [mb32(0) mbstring('stco') mb32(0) mb32(1) ...
0827 mb32(MakeQTMovieStatus.soundStart)];
0828 else
0829 y = [mb32(0) mbstring('stco') mb32(0) ...
0830 mb32(MakeQTMovieStatus.frameNumber) ...
0831 mb32(MakeQTMovieStatus.frameStarts)];
0832 end
0833 y = SetAtomSize(y);
0834
0835
0836 function y = stsc_atom(add_sound_p)
0837 global MakeQTMovieStatus
0838 if add_sound_p
0839 samplesperchunk = MakeQTMovieStatus.soundLength;
0840 else
0841 samplesperchunk = 1;
0842 end
0843
0844 y = [mb32(0) mbstring('stsc') mb32(0) mb32(1) ...
0845 mb32(1) mb32(samplesperchunk) mb32(1)];
0846 y = SetAtomSize(y);
0847
0848
0849 function y = stsd_atom(add_sound_p)
0850 if add_sound_p
0851 desc = raw_sound_description;
0852 else
0853 desc = raw_image_description;
0854 end
0855
0856 y = [mb32(0) mbstring('stsd') mb32(0) mb32(1) desc];
0857 y = SetAtomSize(y);
0858
0859
0860 function y = stss_atom()
0861 y = SetAtomSize([mb32(0) mbstring('stss') mb32(0) mb32(0)]);
0862
0863
0864 function y = stsz_atom(add_sound_p)
0865 global MakeQTMovieStatus
0866 if add_sound_p
0867 y = [mb32(0) mbstring('stsz') mb32(0) mb32(2) ...
0868 mb32(MakeQTMovieStatus.soundLength)];
0869 else
0870 y = [mb32(0) mbstring('stsz') mb32(0) mb32(0) ...
0871 mb32(MakeQTMovieStatus.frameNumber) ...
0872 mb32(MakeQTMovieStatus.frameLengths)];
0873 end
0874 y = SetAtomSize(y);
0875
0876
0877 function y = stts_atom(add_sound_p)
0878 global MakeQTMovieStatus
0879 if add_sound_p
0880 count_duration = [mb32(MakeQTMovieStatus.soundLength) mb32(1)];
0881 else
0882 count_duration = [mb32(MakeQTMovieStatus.frameNumber) ...
0883 mb32(MakeQTMovieStatus.timeScaleExpansion)];
0884 end
0885
0886 y = SetAtomSize([mb32(0) mbstring('stts') mb32(0) mb32(1) count_duration]);
0887
0888
0889 function y = trak_atom(add_sound_p)
0890 global MakeQTMovieStatus
0891
0892 y = [mb32(0) mbstring('trak') ...
0893 tkhd_atom(add_sound_p) ...
0894 edts_atom(add_sound_p) ...
0895 mdia_atom(add_sound_p)];
0896 y = SetAtomSize(y);
0897
0898
0899 function y = tkhd_atom(add_sound_p)
0900 global MakeQTMovieStatus
0901
0902 fixed1 = bitshift(1,16);
0903 frac1 = bitshift(1,30);
0904
0905 if add_sound_p > 0
0906 duration = MakeQTMovieStatus.soundLength / ...
0907 MakeQTMovieStatus.soundRate * ...
0908 MakeQTMovieStatus.timeScale;
0909 else
0910 duration = MakeQTMovieStatus.frameNumber / ...
0911 MakeQTMovieStatus.frameRate * ...
0912 MakeQTMovieStatus.timeScale;
0913 end
0914 duration = ceil(duration);
0915
0916 if(~isfield(MakeQTMovieStatus,'trackNumber'))
0917 MakeQTMovieStatus.trackNumber=0;
0918 end
0919
0920 y = [mb32(0) mbstring('tkhd') ...
0921 mb32(15) ...
0922 mb32(round(now*3600*24)) ...
0923 mb32(round(now*3600*24)) ...
0924 mb32(MakeQTMovieStatus.trackNumber) ...
0925 mb32(0) ...
0926 mb32(duration) ...
0927 mb32(0) mb32(0) ...
0928 mb16(0) mb16(0) mb16(255) mb16(0) ...
0929 mb32(fixed1) mb32(0) mb32(0) ...
0930 mb32(0) mb32(fixed1) mb32(0) ...
0931 mb32(0) mb32(0) mb32(frac1)];
0932
0933 if add_sound_p
0934 y = [y mb32(0) mb32(0)];
0935 else
0936 if(~isfield(MakeQTMovieStatus,'imageSize'))
0937 MakeQTMovieStatus.imageSize=[0 0];
0938 end
0939 y = [y mb32(fliplr(MakeQTMovieStatus.imageSize)*fixed1)];
0940 end
0941 y= SetAtomSize(y);
0942
0943 MakeQTMovieStatus.trackNumber = MakeQTMovieStatus.trackNumber + 1;
0944
0945
0946 function y = udat_atom()
0947 atfmt = [64 double('fmt')];
0948 atday = [64 double('day')];
0949
0950 VersionString = 'Matlab MakeQTMovie version April 7, 2000';
0951
0952 y = [mb32(0) mbstring('udta') ...
0953 SetAtomSize([mb32(0) atfmt mbstring(['Created ' VersionString])]) ...
0954 SetAtomSize([mb32(0) atday ' ' date])];
0955 y = SetAtomSize(y);
0956
0957
0958
0959 function y = vmhd_atom()
0960
0961 y = SetAtomSize([mb32(0) mbstring('vmhd') mb32(0) ...
0962 mb16(64) ...
0963 mb16(0) mb16(0) mb16(0)]);