2 * Unit test suite for AVI Functions
4 * Copyright 2008 Detlef Riekenberg
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
29 #include "wine/test.h"
31 /* ########################### */
33 static const CHAR winetest0
[] = "winetest0";
34 static const CHAR winetest1
[] = "winetest1";
35 static const CHAR testfilename
[] = "wine_avifil32_test.avi";
37 /* ########################### */
39 static const DWORD deffh
[] = /* file_header */
41 FOURCC_RIFF
, 0x34c6 /* length */, formtypeAVI
,
42 FOURCC_LIST
, 0x1ac /* length */,
43 listtypeAVIHEADER
, ckidAVIMAINHDR
, sizeof(MainAVIHeader
),
46 static const MainAVIHeader defmah
=
48 0x00008256, /* dwMicroSecPerFrame */
49 0x000080e8, /* dwMaxBytesPerSec */
50 0x00000000, /* dwPaddingGranularity */
51 0x00000910, /* dwFlags */
52 1, /* dwTotalFrames */
53 0, /* dwInitialFrames */
55 0x00100000, /* dwSuggestedBufferSize*/
58 { 0, 0, 0, 0 } /* dwReserved[4] */
61 static const AVIStreamHeader defash0
=
63 streamtypeVIDEO
, /* fccType */
64 0x30323449, /* fccHandler */
65 0x00000000, /* dwFlags */
68 0, /* dwInitialFrames */
69 0x000003e9, /* dwScale */
70 0x00007530, /* dwRate */
73 0x00100000, /* dwSuggestedBufferSize*/
74 0xffffffff, /* dwQuality */
76 { 0, 0, 0, 0 } /* short left right top bottom */
79 static const AVIStreamHeader defash1
=
82 streamtypeAUDIO
, /* fccType */
87 0, /* dwInitialFrames */
89 0x00002b11, /* dwRate */
91 0x00000665, /* dwLength */
92 0x00003000, /* dwSuggestedBufferSize*/
93 0xffffffff, /* dwQuality */
95 { 0, 0, 0, 0 } /* short left right top bottom */
98 static const PCMWAVEFORMAT defpcmwf
=
103 11025, /* nSamplesPerSec */
104 22050, /* nAvgBytesPerSec */
107 8, /* wBitsPerSample */
110 typedef struct common_avi_headers
{
111 DWORD fh
[sizeof(deffh
)];
113 AVIStreamHeader ash0
;
114 AVIStreamHeader ash1
;
116 } COMMON_AVI_HEADERS
;
118 /* Extra data needed to get the VFW API to load the file */
120 /* MainAVIHeader mah */
121 static const DWORD streamlist
[] =
123 FOURCC_LIST
, 0xd4 /* length */,
124 listtypeSTREAMHEADER
, ckidSTREAMHEADER
, 0x38 /* length */,
126 /* AVIStreamHeader ash0 */
127 static const DWORD videostreamformat
[] =
129 ckidSTREAMFORMAT
, 0x28 /* length */,
130 0x00000028, 0x00000008, 0x00000006, 0x00180001,
131 0x30323449, 0x00000090, 0x00000000, 0x00000000,
132 0x00000000, 0x00000000,
134 static const DWORD padding1
[] =
136 ckidAVIPADDING
, 0xc /* length */,
137 0x00000004, 0x00000000, 0x63643030
139 static const DWORD videopropheader
[] =
141 0x70727076, 0x44 /* length */,
142 0x00000000, 0x00000000,
143 0x0000001e, 0x00000008, 0x00000006, 0x00100009,
144 0x00000008, 0x00000006, 0x00000001, 0x00000006,
145 0x00000008, 0x00000006, 0x00000008, 0x00000000,
146 0x00000000, 0x00000000, 0x00000000,
147 FOURCC_LIST
, 0x70 /* length */,
148 listtypeSTREAMHEADER
, ckidSTREAMHEADER
, 0x38 /* length */,
150 /* AVIStreamHeader ash1 */
151 static const DWORD audiostreamformat_pre
[] =
153 ckidSTREAMFORMAT
, sizeof(PCMWAVEFORMAT
) /* length */,
155 /* PCMWAVEFORMAT pcmwf */
156 static DWORD data
[] =
158 ckidAVIPADDING
, 0xc /* length */,
159 0x00000004, 0x00000000, 0x62773130,
160 ckidAVIPADDING
, 0xc /* length */,
161 0x6c6d646f, 0x686c6d64, 0x000000f8,
162 FOURCC_LIST
, 0x18 /* length */,
164 0x54465349, 0xc /* length */,
165 0x6676614c, 0x332e3235, 0x00302e37,
166 ckidAVIPADDING
, 0x4 /* length */,
168 FOURCC_LIST
, 0xd1b /* length */, listtypeAVIMOVIE
,
172 /* ########################### */
174 static void test_AVISaveOptions(void)
176 AVICOMPRESSOPTIONS options
[2];
177 LPAVICOMPRESSOPTIONS poptions
[2];
178 PAVISTREAM streams
[2] = {NULL
, NULL
};
183 poptions
[0] = &options
[0];
184 poptions
[1] = &options
[1];
185 ZeroMemory(options
, sizeof(options
));
187 SetLastError(0xdeadbeef);
188 hres
= CreateEditableStream(&streams
[0], NULL
);
189 ok(hres
== AVIERR_OK
, "0: got 0x%x and %p (expected AVIERR_OK)\n", hres
, streams
[0]);
191 SetLastError(0xdeadbeef);
192 hres
= CreateEditableStream(&streams
[1], NULL
);
193 ok(hres
== AVIERR_OK
, "1: got 0x%x and %p (expected AVIERR_OK)\n", hres
, streams
[1]);
195 SetLastError(0xdeadbeef);
196 hres
= EditStreamSetNameA(streams
[0], winetest0
);
197 ok(hres
== AVIERR_OK
, "0: got 0x%x (expected AVIERR_OK)\n", hres
);
199 SetLastError(0xdeadbeef);
200 hres
= EditStreamSetNameA(streams
[1], winetest1
);
201 ok(hres
== AVIERR_OK
, "1: got 0x%x (expected AVIERR_OK)\n", hres
);
203 if (winetest_interactive
) {
204 SetLastError(0xdeadbeef);
205 res
= AVISaveOptions(0, ICMF_CHOOSE_DATARATE
|ICMF_CHOOSE_KEYFRAME
| ICMF_CHOOSE_ALLCOMPRESSORS
,
206 2, streams
, poptions
);
207 trace("got %u with 0x%x/%u\n", res
, GetLastError(), GetLastError());
210 SetLastError(0xdeadbeef);
211 lres
= AVISaveOptionsFree(2, poptions
);
212 ok(lres
== AVIERR_OK
, "got 0x%x with 0x%x/%u\n", lres
, GetLastError(), GetLastError());
214 SetLastError(0xdeadbeef);
215 res
= AVIStreamRelease(streams
[0]);
216 ok(res
== 0, "0: got refcount %u (expected 0)\n", res
);
218 SetLastError(0xdeadbeef);
219 res
= AVIStreamRelease(streams
[1]);
220 ok(res
== 0, "1: got refcount %u (expected 0)\n", res
);
224 /* ########################### */
226 static void test_EditStreamSetInfo(void)
228 PAVISTREAM stream
= NULL
;
230 AVISTREAMINFO info
, info2
;
232 hres
= CreateEditableStream(&stream
, NULL
);
233 ok(hres
== AVIERR_OK
, "got 0x%08X, expected AVIERR_OK\n", hres
);
235 /* Size parameter is somehow checked (notice the crash with size=-1 below) */
236 hres
= EditStreamSetInfo(stream
, NULL
, 0);
237 ok( hres
== AVIERR_BADSIZE
, "got 0x%08X, expected AVIERR_BADSIZE\n", hres
);
239 hres
= EditStreamSetInfo(stream
, NULL
, sizeof(AVISTREAMINFO
)-1 );
240 ok( hres
== AVIERR_BADSIZE
, "got 0x%08X, expected AVIERR_BADSIZE\n", hres
);
244 /* Crashing - first parameter not checked */
245 EditStreamSetInfo(NULL
, &info
, sizeof(AVISTREAMINFO
) );
247 /* Crashing - second parameter not checked */
248 EditStreamSetInfo(stream
, NULL
, sizeof(AVISTREAMINFO
) );
250 EditStreamSetInfo(stream
, NULL
, -1);
253 hres
= AVIStreamInfo(stream
, &info
, sizeof(AVISTREAMINFO
) );
254 ok( hres
== 0, "got 0x%08X, expected 0\n", hres
);
256 /* Does the function check what's it's updating ? */
258 #define IS_INFO_UPDATED(m) do { \
259 hres = EditStreamSetInfo(stream, &info, sizeof(AVISTREAMINFO) ); \
260 ok( hres == 0, "got 0x%08X, expected 0\n", hres); \
261 hres = AVIStreamInfo(stream, &info2, sizeof(AVISTREAMINFO) ); \
262 ok( hres == 0, "got 0x%08X, expected 0\n", hres); \
263 ok( info2.m == info.m, "EditStreamSetInfo did not update "#m" parameter\n" ); \
267 IS_INFO_UPDATED(dwStart
);
269 IS_INFO_UPDATED(dwStart
);
272 IS_INFO_UPDATED(wPriority
);
274 IS_INFO_UPDATED(wPriority
);
277 IS_INFO_UPDATED(wLanguage
);
279 IS_INFO_UPDATED(wLanguage
);
282 IS_INFO_UPDATED(dwScale
);
284 IS_INFO_UPDATED(dwScale
);
287 IS_INFO_UPDATED(dwRate
);
289 IS_INFO_UPDATED(dwRate
);
292 IS_INFO_UPDATED(dwQuality
);
294 IS_INFO_UPDATED(dwQuality
);
296 IS_INFO_UPDATED(dwQuality
);
297 info
.dwQuality
= ICQUALITY_HIGH
+1;
298 IS_INFO_UPDATED(dwQuality
);
300 info
.rcFrame
.left
= 0;
301 IS_INFO_UPDATED(rcFrame
.left
);
302 info
.rcFrame
.top
= 0;
303 IS_INFO_UPDATED(rcFrame
.top
);
304 info
.rcFrame
.right
= 0;
305 IS_INFO_UPDATED(rcFrame
.right
);
306 info
.rcFrame
.bottom
= 0;
307 IS_INFO_UPDATED(rcFrame
.bottom
);
309 info
.rcFrame
.left
= -1;
310 IS_INFO_UPDATED(rcFrame
.left
);
311 info
.rcFrame
.top
= -1;
312 IS_INFO_UPDATED(rcFrame
.top
);
313 info
.rcFrame
.right
= -1;
314 IS_INFO_UPDATED(rcFrame
.right
);
315 info
.rcFrame
.bottom
= -1;
316 IS_INFO_UPDATED(rcFrame
.bottom
);
317 AVIStreamRelease(stream
);
318 #undef IS_INFO_UPDATED
322 static void init_test_struct(COMMON_AVI_HEADERS
*cah
)
324 memcpy(cah
->fh
, deffh
, sizeof(deffh
));
328 cah
->pcmwf
= defpcmwf
;
331 static void create_avi_file(const COMMON_AVI_HEADERS
*cah
, char *filename
)
336 hFile
= CreateFile(filename
, GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, FILE_ATTRIBUTE_NORMAL
, NULL
);
338 ok(hFile
!= INVALID_HANDLE_VALUE
, "Couldn't create file\n");
340 WriteFile(hFile
, &cah
->fh
, sizeof(deffh
), &written
, NULL
);
341 WriteFile(hFile
, &cah
->mah
, sizeof(MainAVIHeader
), &written
, NULL
);
342 WriteFile(hFile
, streamlist
, sizeof(streamlist
), &written
, NULL
);
343 WriteFile(hFile
, &cah
->ash0
, 0x38, &written
, NULL
);
344 WriteFile(hFile
, videostreamformat
, sizeof(videostreamformat
), &written
, NULL
);
345 WriteFile(hFile
, padding1
, sizeof(padding1
), &written
, NULL
);
346 WriteFile(hFile
, videopropheader
, sizeof(videopropheader
), &written
, NULL
);
347 WriteFile(hFile
, &cah
->ash1
, 0x38, &written
, NULL
);
348 WriteFile(hFile
, audiostreamformat_pre
, sizeof(audiostreamformat_pre
), &written
, NULL
);
349 WriteFile(hFile
, &cah
->pcmwf
, sizeof(PCMWAVEFORMAT
), &written
, NULL
);
350 WriteFile(hFile
, data
, sizeof(data
), &written
, NULL
);
355 static void test_default_data(void)
357 COMMON_AVI_HEADERS cah
;
358 char filename
[MAX_PATH
];
368 GetTempPath(MAX_PATH
, filename
);
369 strcpy(filename
+strlen(filename
), testfilename
);
371 init_test_struct(&cah
);
372 create_avi_file(&cah
, filename
);
374 res
= AVIFileOpen(&pFile
, filename
, OF_SHARE_DENY_WRITE
, 0L);
375 ok(res
!= AVIERR_BADFORMAT
, "Unable to open file: error1=%u\n", AVIERR_BADFORMAT
);
376 ok(res
!= AVIERR_MEMORY
, "Unable to open file: error2=%u\n", AVIERR_MEMORY
);
377 ok(res
!= AVIERR_FILEREAD
, "Unable to open file: error3=%u\n", AVIERR_FILEREAD
);
378 ok(res
!= AVIERR_FILEOPEN
, "Unable to open file: error4=%u\n", AVIERR_FILEOPEN
);
379 ok(res
!= REGDB_E_CLASSNOTREG
, "Unable to open file: error5=%u\n", REGDB_E_CLASSNOTREG
);
380 ok(res
== 0, "Unable to open file: error=%u\n", res
);
382 res
= AVIFileGetStream(pFile
, &pStream0
, 0, 0);
383 ok(res
== 0, "Unable to open video stream: error=%u\n", res
);
385 res
= AVIFileGetStream(pFile
, &pStream1
, 0, 1);
386 ok(res
== 0, "Unable to open audio stream: error=%u\n", res
);
388 res
= AVIStreamInfo(pStream0
, &asi0
, sizeof(AVISTREAMINFO
));
389 ok(res
== 0, "Unable to read stream info: error=%u\n", res
);
391 res
= AVIStreamInfo(pStream1
, &asi1
, sizeof(AVISTREAMINFO
));
392 ok(res
== 0, "Unable to read stream info: error=%u\n", res
);
394 res
= AVIStreamReadFormat(pStream0
, AVIStreamStart(pStream1
), NULL
, &lSize
);
395 ok(res
== 0, "Unable to read format size: error=%u\n", res
);
397 res
= AVIStreamReadFormat(pStream1
, AVIStreamStart(pStream1
), &wfx
, &lSize
);
398 ok(res
== 0, "Unable to read format: error=%u\n", res
);
400 ok(asi0
.fccType
== streamtypeVIDEO
, "got 0x%x (expected streamtypeVIDEO)\n", asi0
.fccType
);
401 ok(asi0
.fccHandler
== 0x30323449, "got 0x%x (expected 0x30323449)\n", asi0
.fccHandler
);
402 ok(asi0
.dwFlags
== 0, "got %u (expected 0)\n", asi0
.dwFlags
);
403 ok(asi0
.wPriority
== 0, "got %u (expected 0)\n", asi0
.wPriority
);
404 ok(asi0
.wLanguage
== 0, "got %u (expected 0)\n", asi0
.wLanguage
);
405 ok(asi0
.dwScale
== 1001, "got %u (expected 1001)\n", asi0
.dwScale
);
406 ok(asi0
.dwRate
== 30000, "got %u (expected 30000)\n", asi0
.dwRate
);
407 ok(asi0
.dwStart
== 0, "got %u (expected 0)\n", asi0
.dwStart
);
408 ok(asi0
.dwLength
== 1, "got %u (expected 1)\n", asi0
.dwLength
);
409 ok(asi0
.dwInitialFrames
== 0, "got %u (expected 0)\n", asi0
.dwInitialFrames
);
410 ok(asi0
.dwSuggestedBufferSize
== 0, "got %u (expected 0)\n", asi0
.dwSuggestedBufferSize
);
411 ok(asi0
.dwQuality
== 0xffffffff, "got 0x%x (expected 0xffffffff)\n", asi0
.dwQuality
);
412 ok(asi0
.dwSampleSize
== 0, "got %u (expected 0)\n", asi0
.dwSampleSize
);
413 ok(asi0
.rcFrame
.left
== 0, "got %u (expected 0)\n", asi0
.rcFrame
.left
);
414 ok(asi0
.rcFrame
.top
== 0, "got %u (expected 0)\n", asi0
.rcFrame
.top
);
415 ok(asi0
.rcFrame
.right
== 8, "got %u (expected 8)\n", asi0
.rcFrame
.right
); /* these are based on the values in the mah and not */
416 ok(asi0
.rcFrame
.bottom
== 6, "got %u (expected 6)\n", asi0
.rcFrame
.bottom
);/* on the ones in the ash which are 0 here */
417 ok(asi0
.dwEditCount
== 0, "got %u (expected 0)\n", asi0
.dwEditCount
);
418 ok(asi0
.dwFormatChangeCount
== 0, "got %u (expected 0)\n", asi0
.dwFormatChangeCount
);
420 ok(asi1
.fccType
== streamtypeAUDIO
, "got 0x%x (expected streamtypeVIDEO)\n", asi1
.fccType
);
421 ok(asi1
.fccHandler
== 0x1, "got 0x%x (expected 0x1)\n", asi1
.fccHandler
);
422 ok(asi1
.dwFlags
== 0, "got %u (expected 0)\n", asi1
.dwFlags
);
423 ok(asi1
.wPriority
== 0, "got %u (expected 0)\n", asi1
.wPriority
);
424 ok(asi1
.wLanguage
== 0, "got %u (expected 0)\n", asi1
.wLanguage
);
425 ok(asi1
.dwScale
== 1, "got %u (expected 1)\n", asi1
.dwScale
);
426 ok(asi1
.dwRate
== 11025, "got %u (expected 11025)\n", asi1
.dwRate
);
427 ok(asi1
.dwStart
== 0, "got %u (expected 0)\n", asi1
.dwStart
);
428 ok(asi1
.dwLength
== 1637, "got %u (expected 1637)\n", asi1
.dwLength
);
429 ok(asi1
.dwInitialFrames
== 0, "got %u (expected 0)\n", asi1
.dwInitialFrames
);
430 ok(asi1
.dwSuggestedBufferSize
== 0, "got %u (expected 0)\n", asi1
.dwSuggestedBufferSize
);
431 ok(asi1
.dwQuality
== 0xffffffff, "got 0x%x (expected 0xffffffff)\n", asi1
.dwQuality
);
432 ok(asi1
.dwSampleSize
== 2, "got %u (expected 2)\n", asi1
.dwSampleSize
);
433 ok(asi1
.rcFrame
.left
== 0, "got %u (expected 0)\n", asi1
.rcFrame
.left
);
434 ok(asi1
.rcFrame
.top
== 0, "got %u (expected 0)\n", asi1
.rcFrame
.top
);
435 ok(asi1
.rcFrame
.right
== 0, "got %u (expected 0)\n", asi1
.rcFrame
.right
);
436 ok(asi1
.rcFrame
.bottom
== 0, "got %u (expected 0)\n", asi1
.rcFrame
.bottom
);
437 ok(asi1
.dwEditCount
== 0, "got %u (expected 0)\n", asi1
.dwEditCount
);
438 ok(asi1
.dwFormatChangeCount
== 0, "got %u (expected 0)\n", asi1
.dwFormatChangeCount
);
440 ok(wfx
.wFormatTag
== 1, "got %u (expected 1)\n",wfx
.wFormatTag
);
441 ok(wfx
.nChannels
== 2, "got %u (expected 2)\n",wfx
.nChannels
);
442 ok(wfx
.wFormatTag
== 1, "got %u (expected 1)\n",wfx
.wFormatTag
);
443 ok(wfx
.nSamplesPerSec
== 11025, "got %u (expected 11025)\n",wfx
.nSamplesPerSec
);
444 ok(wfx
.nAvgBytesPerSec
== 22050, "got %u (expected 22050)\n",wfx
.nAvgBytesPerSec
);
445 ok(wfx
.nBlockAlign
== 2, "got %u (expected 2)\n",wfx
.nBlockAlign
);
447 AVIStreamRelease(pStream0
);
448 AVIStreamRelease(pStream1
);
449 AVIFileRelease(pFile
);
450 ok(DeleteFile(filename
) !=0, "Deleting file %s failed\n", filename
);
453 static void test_amh_corruption(void)
455 COMMON_AVI_HEADERS cah
;
456 char filename
[MAX_PATH
];
460 GetTempPath(MAX_PATH
, filename
);
461 strcpy(filename
+strlen(filename
), testfilename
);
463 /* Make sure only AVI files with the proper headers will be loaded */
464 init_test_struct(&cah
);
465 cah
.fh
[3] = mmioFOURCC('A', 'V', 'i', ' ');
467 create_avi_file(&cah
, filename
);
468 res
= AVIFileOpen(&pFile
, filename
, OF_SHARE_DENY_WRITE
, 0L);
469 ok(res
!= 0, "Able to open file: error=%u\n", res
);
471 ok(DeleteFile(filename
) !=0, "Deleting file %s failed\n", filename
);
474 static void test_ash1_corruption(void)
476 COMMON_AVI_HEADERS cah
;
477 char filename
[MAX_PATH
];
483 GetTempPath(MAX_PATH
, filename
);
484 strcpy(filename
+strlen(filename
), testfilename
);
486 /* Corrupt the sample size in the audio stream header */
487 init_test_struct(&cah
);
488 cah
.ash1
.dwSampleSize
= 0xdeadbeef;
490 create_avi_file(&cah
, filename
);
492 res
= AVIFileOpen(&pFile
, filename
, OF_SHARE_DENY_WRITE
, 0L);
493 ok(res
== 0, "Unable to open file: error=%u\n", res
);
495 res
= AVIFileGetStream(pFile
, &pStream1
, 0, 1);
496 ok(res
== 0, "Unable to open audio stream: error=%u\n", res
);
498 res
= AVIStreamInfo(pStream1
, &asi1
, sizeof(AVISTREAMINFO
));
499 ok(res
== 0, "Unable to read stream info: error=%u\n", res
);
501 /* The result will still be 2, because the value is dynamically replaced with the nBlockAlign
502 value from the stream format header. The next test will prove this */
503 ok(asi1
.dwSampleSize
== 2, "got %u (expected 2)\n", asi1
.dwSampleSize
);
505 AVIStreamRelease(pStream1
);
506 AVIFileRelease(pFile
);
507 ok(DeleteFile(filename
) !=0, "Deleting file %s failed\n", filename
);
510 static void test_ash1_corruption2(void)
512 COMMON_AVI_HEADERS cah
;
513 char filename
[MAX_PATH
];
519 GetTempPath(MAX_PATH
, filename
);
520 strcpy(filename
+strlen(filename
), testfilename
);
522 /* Corrupt the block alignment in the audio format header */
523 init_test_struct(&cah
);
524 cah
.pcmwf
.wf
.nBlockAlign
= 0xdead;
526 create_avi_file(&cah
, filename
);
528 res
= AVIFileOpen(&pFile
, filename
, OF_SHARE_DENY_WRITE
, 0L);
529 ok(res
== 0, "Unable to open file: error=%u\n", res
);
531 res
= AVIFileGetStream(pFile
, &pStream1
, 0, 1);
532 ok(res
== 0, "Unable to open audio stream: error=%u\n", res
);
534 ok(AVIStreamInfo(pStream1
, &asi1
, sizeof(AVISTREAMINFO
)) == 0, "Unable to read stream info\n");
536 /* The result will also be the corrupt value, as explained above. */
537 ok(asi1
.dwSampleSize
== 0xdead, "got 0x%x (expected 0xdead)\n", asi1
.dwSampleSize
);
539 AVIStreamRelease(pStream1
);
540 AVIFileRelease(pFile
);
541 ok(DeleteFile(filename
) !=0, "Deleting file %s failed\n", filename
);
544 /* ########################### */
550 test_EditStreamSetInfo();
551 test_AVISaveOptions();
553 test_amh_corruption();
554 test_ash1_corruption();
555 test_ash1_corruption2();