mirror of
https://github.com/aaru-dps/libaaruformat.git
synced 2025-12-16 19:24:40 +00:00
Add convert command to AaruFormat tool for image conversion
This commit is contained in:
@@ -6,6 +6,6 @@ find_package(Argtable3 CONFIG REQUIRED)
|
|||||||
include_directories(${ICU_INCLUDE_DIRS})
|
include_directories(${ICU_INCLUDE_DIRS})
|
||||||
|
|
||||||
add_executable(aaruformattool main.c version.h aaruformattool.h identify.c info.c helpers.c read.c printhex.c verify.c ecc_cd.c
|
add_executable(aaruformattool main.c version.h aaruformattool.h identify.c info.c helpers.c read.c printhex.c verify.c ecc_cd.c
|
||||||
commands.h commands.c usage.h usage.c compare.c termbox2.h)
|
commands.h commands.c usage.h usage.c compare.c convert.c termbox2.h)
|
||||||
target_link_libraries(aaruformattool "aaruformat" argtable3::argtable3)
|
target_link_libraries(aaruformattool "aaruformat" argtable3::argtable3)
|
||||||
target_link_libraries(aaruformattool "aaruformat" ICU::uc)
|
target_link_libraries(aaruformattool "aaruformat" ICU::uc)
|
||||||
|
|||||||
@@ -34,5 +34,6 @@ int verify_sectors(const char *path);
|
|||||||
bool check_cd_sector_channel(CdEccContext *context, uint8_t *sector, bool *unknown, bool *has_edc, bool *edc_correct,
|
bool check_cd_sector_channel(CdEccContext *context, uint8_t *sector, bool *unknown, bool *has_edc, bool *edc_correct,
|
||||||
bool *has_ecc_p, bool *ecc_p_correct, bool *has_ecc_q, bool *ecc_q_correct);
|
bool *has_ecc_p, bool *ecc_p_correct, bool *has_ecc_q, bool *ecc_q_correct);
|
||||||
int compare(char *path1, char *path2);
|
int compare(char *path1, char *path2);
|
||||||
|
int convert(char *input_path, char *output_path);
|
||||||
|
|
||||||
#endif // LIBAARUFORMAT_TOOL_AARUFORMATTOOL_H_
|
#endif // LIBAARUFORMAT_TOOL_AARUFORMATTOOL_H_
|
||||||
|
|||||||
@@ -132,6 +132,26 @@ int cmd_verify(int argc, char *argv[]) { return cmd_verify_common(argc, argv, fa
|
|||||||
|
|
||||||
int cmd_verify_sectors(int argc, char *argv[]) { return cmd_verify_common(argc, argv, true); }
|
int cmd_verify_sectors(int argc, char *argv[]) { return cmd_verify_common(argc, argv, true); }
|
||||||
|
|
||||||
|
int cmd_convert(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
struct arg_str *input_filename = arg_str1(NULL, NULL, "<input>", "Input image file");
|
||||||
|
struct arg_str *output_filename = arg_str1(NULL, NULL, "<output>", "Output image file");
|
||||||
|
struct arg_end *end = arg_end(10);
|
||||||
|
void *argtable[] = {input_filename, output_filename, end};
|
||||||
|
|
||||||
|
if(arg_parse(argc, argv, argtable) > 0)
|
||||||
|
{
|
||||||
|
arg_print_errors(stderr, end, "convert");
|
||||||
|
usage_convert();
|
||||||
|
arg_freetable(argtable, sizeof(argtable) / sizeof(argtable[0]));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int result = convert(input_filename->sval[0], output_filename->sval[0]);
|
||||||
|
arg_freetable(argtable, sizeof(argtable) / sizeof(argtable[0]));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
Command commands[] = {
|
Command commands[] = {
|
||||||
{ "identify", cmd_identify},
|
{ "identify", cmd_identify},
|
||||||
{ "info", cmd_info},
|
{ "info", cmd_info},
|
||||||
@@ -140,6 +160,7 @@ Command commands[] = {
|
|||||||
{ "verify", cmd_verify},
|
{ "verify", cmd_verify},
|
||||||
{"verify_sectors", cmd_verify_sectors},
|
{"verify_sectors", cmd_verify_sectors},
|
||||||
{ "compare", cmd_compare},
|
{ "compare", cmd_compare},
|
||||||
|
{ "convert", cmd_convert},
|
||||||
};
|
};
|
||||||
|
|
||||||
const size_t num_commands = sizeof(commands) / sizeof(commands[0]);
|
const size_t num_commands = sizeof(commands) / sizeof(commands[0]);
|
||||||
|
|||||||
@@ -39,5 +39,6 @@ int cmd_read_long(int argc, char *argv[]);
|
|||||||
int cmd_verify(int argc, char *argv[]);
|
int cmd_verify(int argc, char *argv[]);
|
||||||
int cmd_verify_sectors(int argc, char *argv[]);
|
int cmd_verify_sectors(int argc, char *argv[]);
|
||||||
int cmd_compare(int argc, char *argv[]);
|
int cmd_compare(int argc, char *argv[]);
|
||||||
|
int cmd_convert(int argc, char *argv[]);
|
||||||
|
|
||||||
#endif // LIBAARUFORMAT_COMMANDS_H
|
#endif // LIBAARUFORMAT_COMMANDS_H
|
||||||
|
|||||||
125
tool/convert.c
Normal file
125
tool/convert.c
Normal file
@@ -0,0 +1,125 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the Aaru Data Preservation Suite.
|
||||||
|
* Copyright (c) 2019-2025 Natalia Portillo.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include <aaruformat.h>
|
||||||
|
|
||||||
|
#include "aaruformattool.h"
|
||||||
|
|
||||||
|
int convert(char *input_path, char *output_path)
|
||||||
|
{
|
||||||
|
aaruformatContext *input_ctx = NULL;
|
||||||
|
aaruformatContext *output_ctx = NULL;
|
||||||
|
int32_t res = 0;
|
||||||
|
uint32_t sector_size = 0;
|
||||||
|
uint64_t total_sectors = 0;
|
||||||
|
uint8_t *sector_data = NULL;
|
||||||
|
|
||||||
|
printf("Converting image from %s to %s...\n", input_path, output_path);
|
||||||
|
|
||||||
|
// Open input image
|
||||||
|
input_ctx = aaruf_open(input_path);
|
||||||
|
if(input_ctx == NULL)
|
||||||
|
{
|
||||||
|
printf("Error %d when opening input AaruFormat image.\n", errno);
|
||||||
|
return errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get image information from input
|
||||||
|
total_sectors = input_ctx->imageInfo.Sectors;
|
||||||
|
sector_size = input_ctx->imageInfo.SectorSize;
|
||||||
|
|
||||||
|
printf("Input image has %llu sectors of %u bytes each.\n", (unsigned long long)total_sectors, sector_size);
|
||||||
|
|
||||||
|
// Create output image
|
||||||
|
output_ctx = aaruf_create(output_path, input_ctx->imageInfo.MediaType, sector_size, total_sectors,
|
||||||
|
0, // negative sectors
|
||||||
|
0, // overflow sectors
|
||||||
|
NULL, // options
|
||||||
|
(const uint8_t *)"aaruformattool",
|
||||||
|
14, // application name length
|
||||||
|
1, // major version
|
||||||
|
0 // minor version
|
||||||
|
);
|
||||||
|
|
||||||
|
if(output_ctx == NULL)
|
||||||
|
{
|
||||||
|
printf("Error %d when creating output AaruFormat image.\n", errno);
|
||||||
|
aaruf_close(input_ctx);
|
||||||
|
return errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Allocate buffer for sector data
|
||||||
|
sector_data = malloc(sector_size);
|
||||||
|
if(sector_data == NULL)
|
||||||
|
{
|
||||||
|
printf("Error allocating memory for sector buffer.\n");
|
||||||
|
aaruf_close(input_ctx);
|
||||||
|
aaruf_close(output_ctx);
|
||||||
|
return AARUF_ERROR_NOT_ENOUGH_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy sectors from input to output
|
||||||
|
for(uint64_t sector = 0; sector < total_sectors; sector++)
|
||||||
|
{
|
||||||
|
uint32_t read_length = sector_size;
|
||||||
|
|
||||||
|
// Show progress every 1000 sectors
|
||||||
|
if(sector % 1000 == 0 || sector == total_sectors - 1)
|
||||||
|
{
|
||||||
|
printf("\rProgress: %llu/%llu sectors (%.1f%%)", (unsigned long long)sector + 1,
|
||||||
|
(unsigned long long)total_sectors, ((double)(sector + 1) / total_sectors) * 100.0);
|
||||||
|
fflush(stdout);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read sector from input
|
||||||
|
res = aaruf_read_sector(input_ctx, sector, sector_data, &read_length);
|
||||||
|
if(res != AARUF_STATUS_OK)
|
||||||
|
{
|
||||||
|
printf("\nError %d when reading sector %llu from input image.\n", res, (unsigned long long)sector);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write sector to output
|
||||||
|
res = aaruf_write_sector(output_ctx, sector, sector_data, 0, read_length);
|
||||||
|
if(res != AARUF_STATUS_OK)
|
||||||
|
{
|
||||||
|
printf("\nError %d when writing sector %llu to output image.\n", res, (unsigned long long)sector);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
// Clean up
|
||||||
|
free(sector_data);
|
||||||
|
aaruf_close(input_ctx);
|
||||||
|
res = aaruf_close(output_ctx);
|
||||||
|
|
||||||
|
if(res == AARUF_STATUS_OK)
|
||||||
|
printf("Conversion completed successfully.\n");
|
||||||
|
else
|
||||||
|
printf("Conversion failed with error %d.\n", res);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
14
tool/usage.c
14
tool/usage.c
@@ -39,7 +39,9 @@ void usage()
|
|||||||
printf(" read Reads a sector and prints it out on screen.\n");
|
printf(" read Reads a sector and prints it out on screen.\n");
|
||||||
printf(" read_long Reads a sector with all its prefixes and suffixes.\n");
|
printf(" read_long Reads a sector with all its prefixes and suffixes.\n");
|
||||||
printf(" verify Verifies the integrity of blocks in an image.\n");
|
printf(" verify Verifies the integrity of blocks in an image.\n");
|
||||||
printf(" verify_sectors Verifies the integrity of all sectors in an image.\n\n");
|
printf(" verify_sectors Verifies the integrity of all sectors in an image.\n");
|
||||||
|
printf(" compare Compares two AaruFormat images.\n");
|
||||||
|
printf(" convert Converts an AaruFormat image to another AaruFormat image.\n\n");
|
||||||
printf("For help with any verb, run:\n");
|
printf("For help with any verb, run:\n");
|
||||||
printf(" aaruformattool <verb> --help\n");
|
printf(" aaruformattool <verb> --help\n");
|
||||||
}
|
}
|
||||||
@@ -109,3 +111,13 @@ void usage_compare()
|
|||||||
printf(" <filename1> Path to first image file.\n");
|
printf(" <filename1> Path to first image file.\n");
|
||||||
printf(" <filename2> Path to second image file.\n");
|
printf(" <filename2> Path to second image file.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void usage_convert()
|
||||||
|
{
|
||||||
|
printf("\nUsage:\n");
|
||||||
|
printf(" aaruformattool convert <input> <output>\n\n");
|
||||||
|
printf("Converts an AaruFormat image by reading all sectors from input and writing them to output.\n");
|
||||||
|
printf("Arguments:\n");
|
||||||
|
printf(" <input> Path to input image file.\n");
|
||||||
|
printf(" <output> Path to output image file.\n");
|
||||||
|
}
|
||||||
|
|||||||
@@ -29,5 +29,6 @@ void usage_read_long();
|
|||||||
void usage_verify();
|
void usage_verify();
|
||||||
void usage_verify_sectors();
|
void usage_verify_sectors();
|
||||||
void usage_compare();
|
void usage_compare();
|
||||||
|
void usage_convert();
|
||||||
|
|
||||||
#endif // LIBAARUFORMAT_USAGE_H
|
#endif // LIBAARUFORMAT_USAGE_H
|
||||||
|
|||||||
Reference in New Issue
Block a user