bool LASunzipper::return_error(const char* error) { char err[256]; sprintf(err, "%s (LASzip v%d.%dr%d)", error, LASZIP_VERSION_MAJOR, LASZIP_VERSION_MINOR, LASZIP_VERSION_REVISION); if (error_string) free(error_string); error_string = LASCopyString(err); return false; }
int main(int argc, char *argv[]) { /*Initialize the catalog locks*/ MT_lock_init(&dataLock); MT_cond_init(&mainCond); MT_cond_init(&writeTCond); MT_cond_init(&readCond); char* file_name_in = 0; char* file_name_out = 0; char separator_sign = ' '; char* parse_string = "xyz"; char* buffer; char printstring[256]; LASReaderH reader = NULL; LASHeaderH header = NULL; LASPointH p = NULL; FILE** files_out = NULL; int len, j; int64_t mortonkey = 0; unsigned int index = 0; int num_files_in = 0, num_files_out = 0, num_files, num_of_entries=0, check = 0, num_read_threads = DEFAULT_NUM_READ_THREADS; int i; pthread_t *writeThreads = NULL; pthread_t *readThreads = NULL; struct readThreadArgs *dataRead = NULL; boolean input_file = FALSE; int64_t global_offset_x = 0; int64_t global_offset_y = 0; double scale_x; double scale_y; if (argc == 1) { usage(); exit(0); } /*Allocate space for input files*/ files_name_in = (char**) malloc(sizeof(char*)*DEFAULT_NUM_INPUT_FILES); for (i = 1; i < argc; i++) { if ( strcmp(argv[i],"-h") == 0 || strcmp(argv[i],"--help") == 0 ) { usage(); exit(0); } else if ( strcmp(argv[i],"-v") == 0 || strcmp(argv[i],"--verbose") == 0 ) { verbose = TRUE; } else if ( strcmp(argv[i],"--num_read_threads") == 0) { num_read_threads = atoi(argv[++i]); } else if ( strcmp(argv[i],"-s") == 0 || strcmp(argv[i],"--skip_invalid") == 0 ) { skip_invalid = TRUE; } else if ( strcmp(argv[i], "--parse") == 0 || strcmp(argv[i], "-parse") == 0 ) { i++; parse_string = argv[i]; } else if ( strcmp(argv[i], "--moffset") == 0 || strcmp(argv[i], "-moffset") == 0 ) { i++; buffer = strtok (argv[i], ","); j = 0; while (buffer) { if (j == 0) { global_offset_x = S64(buffer); } else if (j == 1) { global_offset_y = S64(buffer); } j++; buffer = strtok (NULL, ","); while (buffer && *buffer == '\040') buffer++; } if (j != 2){ fprintf(stderr, "Only two int64_t are required in moffset option!\n"); exit(1); } } else if ( strcmp(argv[i], "--check") == 0 || strcmp(argv[i], "-check") == 0 ) { i++; check = 1; buffer = strtok (argv[i], ","); j = 0; while (buffer) { if (j == 0) { sscanf(buffer, "%lf", &scale_x); } else if (j == 1) { sscanf(buffer, "%lf", &scale_y); } j++; buffer = strtok (NULL, ","); while (buffer && *buffer == '\040') buffer++; } if (j != 2){ fprintf(stderr, "Only two doubles are required in moffset option!\n"); exit(1); } } else if ( strcmp(argv[i],"--input") == 0 || strcmp(argv[i],"-input") == 0 || strcmp(argv[i],"-i") == 0 || strcmp(argv[i],"-in") == 0 ) { i++; files_name_in[num_files_in++] = argv[i]; if (num_files_in % DEFAULT_NUM_INPUT_FILES) files_name_in = (char**) realloc(files_name_in, (num_files_in*2)*sizeof(char*)); } else if (strcmp(argv[i],"--file") == 0 || strcmp(argv[i],"-file") == 0 || strcmp(argv[i],"-f") == 0 ) { i++; int read; char line_buffer[BUFSIZ]; FILE* in = NULL; in = fopen(argv[i], "r"); if (!in) { fprintf(stderr, "ERROR: the path for file containing the input files is invalid %s\n", argv[i]); exit(1); } while (fgets(line_buffer, sizeof(line_buffer), in)) { line_buffer[strlen(line_buffer)-1]='\0'; files_name_in[num_files_in++] = strdup(line_buffer); if (num_files_in % DEFAULT_NUM_INPUT_FILES) files_name_in = (char**) realloc(files_name_in, (num_files_in*2)*sizeof(char*)); } fclose(in); input_file = TRUE; } else if ((num_files_in != 0) && num_files_out == 0) { file_name_out = argv[i]; num_files_out++; } else { fprintf(stderr, "ERROR: unknown argument '%s'\n",argv[i]); usage(); exit(1); } } /* end looping through argc/argv */ num_of_entries = strlen(parse_string); if (num_files_in == 0) { LASError_Print("No input filename was specified"); usage(); exit(1); } num_files = num_files_in; /*Entries metadata*/ i = 0; for (;;) { switch (parse_string[i]) { /* // the morton code on xy */ case 'k': entries[i] = ENTRY_k; entriesType[i] = sizeof(int64_t); /*Changes for Oscar's new Morton code function*/ //entriesFunc[i] = (void*)morton2D_encode; entriesFunc[i] = (void*)morton2D_encodeOscar; break; /* // the x coordinate double*/ case 'x': entries[i] = ENTRY_x; entriesType[i] = sizeof(double); entriesFunc[i] = (void*)LASPoint_GetX; break; /* // the y coordinate double*/ case 'y': entries[i] = ENTRY_y; entriesType[i] = sizeof(double); entriesFunc[i] = (void*)LASPoint_GetY; break; /* // the z coordinate double*/ case 'z': entries[i] = ENTRY_z; entriesType[i] = sizeof(double); entriesFunc[i] = (void*)LASPoint_GetZ; break; /* // the X coordinate decimal*/ case 'X': entries[i] = ENTRY_X; entriesType[i] = sizeof(int); entriesFunc[i] = (void*)LASPoint_GetX; break; /* // the y coordinate decimal*/ case 'Y': entries[i] = ENTRY_Y; entriesType[i] = sizeof(int); entriesFunc[i] = (void*)LASPoint_GetY; break; /* // the z coordinate decimal*/ case 'Z': entries[i] = ENTRY_Z; entriesType[i] = sizeof(int); entriesFunc[i] = (void*)LASPoint_GetZ; break; /* // the gps-time */ case 't': entries[i] = ENTRY_t; entriesType[i] = sizeof(double); entriesFunc[i] = (void*)LASPoint_GetTime; break; /* // the intensity */ case 'i': entries[i] = ENTRY_i; entriesType[i] = sizeof(int); entriesFunc[i] = (void*)LASPoint_GetIntensity; break; /* the scan angle */ case 'a': entries[i] = ENTRY_a; entriesType[i] = sizeof(int); entriesFunc[i] = (void*)LASPoint_GetScanAngleRank; break; /* the number of the return */ case 'r': entries[i] = ENTRY_r; entriesType[i] = sizeof(int); entriesFunc[i] = (void*)LASPoint_GetReturnNumber; break; /* the classification */ case 'c': entries[i] = ENTRY_c; entriesType[i] = sizeof(int); entriesFunc[i] = (void*)LASPoint_GetClassification; break; /* the user data */ case 'u': entries[i] = ENTRY_u; entriesType[i] = sizeof(int); entriesFunc[i] = (void*)LASPoint_GetUserData; break; /* the number of returns of given pulse */ case 'n': entries[i] = ENTRY_n; entriesType[i] = sizeof(int); entriesFunc[i] = (void*)LASPoint_GetNumberOfReturns; break; /* the red channel color */ case 'R': entries[i] = ENTRY_R; entriesType[i] = sizeof(int); entriesFunc[i] = (void*)LASColor_GetRed; break; /* the green channel color */ case 'G': entries[i] = ENTRY_G; entriesType[i] = sizeof(int); entriesFunc[i] = (void*)LASColor_GetGreen; break; /* the blue channel color */ case 'B': entries[i] = ENTRY_B; entriesType[i] = sizeof(int); entriesFunc[i] = (void*)LASColor_GetBlue; break; case 'M': entries[i] = ENTRY_M; entriesType[i] = sizeof(unsigned int); break; case 'p': entries[i] = ENTRY_p; entriesType[i] = sizeof(int); entriesFunc[i] = (void*)LASPoint_GetPointSourceId; break; /* the edge of flight line flag */ case 'e': entries[i] = ENTRY_e; entriesType[i] = sizeof(int); entriesFunc[i] = (void*)LASPoint_GetFlightLineEdge; break; /* the direction of scan flag */ case 'd': entries[i] = ENTRY_d; entriesType[i] = sizeof(int); entriesFunc[i] = (void*)LASPoint_GetScanDirection; break; } i++; if (parse_string[i] == 0) { break; } } /*Prepare the output files*/ if (file_name_out == NULL) { len = (int)strlen(file_name_in); file_name_out = LASCopyString(file_name_in); if (file_name_out[len-3] == '.' && file_name_out[len-2] == 'g' && file_name_out[len-1] == 'z') { len = len - 4; } while (len > 0 && file_name_out[len] != '.') { len--; } file_name_out[len] = '\0'; } char *str = malloc(sizeof(char)*(strlen(file_name_out)+12)); files_out = (FILE**) malloc(sizeof(FILE*)*num_of_entries); for (i = 0; i < num_of_entries; i++) { sprintf(str, "%s_col_%c.dat", file_name_out, parse_string[i]); if(doesFileExist(str)) { remove(str); } files_out[i] = fopen(str, "wb"); if (files_out[i] == 0) { LASError_Print("Could not open file for write"); usage(); exit(1); } } free(str); /*Initialize structures for the reading threads*/ //data = (struct writeT**) malloc(num_read_threads*sizeof(struct writeT*)); //Malloc is more efficient than calloc data = (struct writeT**) calloc(num_read_threads, sizeof(struct writeT*)); dataRead = (struct readThreadArgs*) malloc(sizeof(struct readThreadArgs)*num_read_threads); /* Launch read Threads */ stop = 0; readThreads = (pthread_t*) malloc(sizeof(pthread_t)*num_read_threads); for (i=0; i < num_read_threads; i++) { dataRead[i].id = i; dataRead[i].num_read_threads = num_read_threads; dataRead[i].num_of_entries = num_of_entries; dataRead[i].check = check; dataRead[i].global_offset_x = global_offset_x; dataRead[i].global_offset_y = global_offset_y; dataRead[i].scale_x = scale_x; dataRead[i].scale_y = scale_y; pthread_create(&readThreads[i], NULL, readFile, (void*)dataRead); } int writeIndex = 0; writeThreads = (pthread_t*) malloc(sizeof(pthread_t)*num_of_entries); /* Launch Threads */ struct writeThreadArgs *dataWrite = (struct writeThreadArgs *) malloc(sizeof(struct writeThreadArgs) *num_of_entries); for (i = 0; i < num_of_entries; i++) { dataWrite[i].id = i; dataWrite[i].out = files_out[i]; pthread_create(&writeThreads[i], NULL, writeFile, (void*)(&dataWrite[i])); } sleep(1); //Do we need to comment this one out!? int done = 0; while (num_files) { /*Obtain lock over data to get the pointer*/ MT_set_lock(&dataLock); dataWriteT = data[writeIndex]; while (dataWriteT == NULL) { /*Sleep and wait for data to be read*/ MT_cond_wait(&mainCond,&dataLock); dataWriteT = data[writeIndex]; } data[writeIndex] = NULL; //Release the lock /*Tell the write threads there is new data*/ pthread_cond_broadcast(&writeTCond); /*Tell the read threads there is a new buf empty*/ pthread_cond_broadcast(&readCond); MT_unset_lock(&dataLock); /*Keep looping*/ writeIndex++; writeIndex = (writeIndex % num_read_threads); MT_set_lock(&dataLock); while (done == 0) { /*Sleep and wait for data to be read*/ MT_cond_wait(&mainCond,&dataLock); done = 1; for (i = 0; i < num_of_entries; i++) { if (dataWriteT[i].values != NULL) { done = 0; break; } } } num_files--; if (verbose) printf("Files to go %d\n", num_files); free(dataWriteT); dataWriteT = NULL; done = 0; MT_unset_lock(&dataLock); } /*Tell the write threads to exit*/ MT_set_lock(&dataLock); stop = 1; pthread_cond_broadcast(&writeTCond); MT_unset_lock(&dataLock); /* Wait for Threads to Finish */ for (i=0; i<num_of_entries; i++) { pthread_join(writeThreads[i], NULL); } free(dataWrite); free(writeThreads); MT_cond_destroy(&readCond); MT_cond_destroy(&writeTCond); MT_cond_destroy(&mainCond); MT_lock_destroy(&dataLock); for (i = 0; i < num_of_entries; i++) { fflush(files_out[i]); if (verbose) printf("close file %d\n", i); fsync(files_out[i]); fclose(files_out[i]); } free(files_out); if (input_file) { for (i=0 ; i < num_files_in; i++) free(files_name_in[i]); free(files_name_in); } free(dataRead); if (readThreads) free(readThreads); return 0; }
int main(int argc, char *argv[]) { int i; int j; char* buffer; int use_stdout = FALSE; int skip_invalid = FALSE; int num_entries = 0; int verbose = FALSE; char* file_name_in = 0; char* file_name_out = 0; char separator_sign = ' '; char* parse_string = "xyz"; int64_t global_offset_x = 0; int64_t global_offset_y = 0; int check = FALSE; double scale_x; double scale_y; LASReaderH reader = NULL; LASHeaderH header = NULL; LASPointH p = NULL; FILE* file_out; int len; unsigned int index = 0; if (argc == 1) { usage(); exit(0); } for (i = 1; i < argc; i++) { if ( strcmp(argv[i],"-h") == 0 || strcmp(argv[i],"-help") == 0 || strcmp(argv[i],"--help") == 0 ) { usage(); exit(0); } else if ( strcmp(argv[i],"-v") == 0 || strcmp(argv[i],"--verbose") == 0 ) { verbose = TRUE; } else if ( strcmp(argv[i],"-s") == 0 || strcmp(argv[i],"--skip_invalid") == 0 ) { skip_invalid = TRUE; } else if ( strcmp(argv[i], "--parse") == 0 || strcmp(argv[i], "-parse") == 0 ) { i++; parse_string = argv[i]; } else if ( strcmp(argv[i], "--moffset") == 0 || strcmp(argv[i], "-moffset") == 0 ) { i++; buffer = strtok (argv[i], ","); j = 0; while (buffer) { if (j == 0) { global_offset_x = S64(buffer); } else if (j == 1) { global_offset_y = S64(buffer); } j++; buffer = strtok (NULL, ","); while (buffer && *buffer == '\040') buffer++; } if (j != 2){ fprintf(stderr, "Only two int64_t are required in moffset option!\n"); exit(1); } } else if ( strcmp(argv[i], "--check") == 0 || strcmp(argv[i], "-check") == 0 ) { i++; check = TRUE; buffer = strtok (argv[i], ","); j = 0; while (buffer) { if (j == 0) { sscanf(buffer, "%lf", &scale_x); } else if (j == 1) { sscanf(buffer, "%lf", &scale_y); } j++; buffer = strtok (NULL, ","); while (buffer && *buffer == '\040') buffer++; } if (j != 2){ fprintf(stderr, "Only two doubles are required in moffset option!\n"); exit(1); } } else if ( strcmp(argv[i], "--stdout") == 0 ) { use_stdout = TRUE; } else if ( strcmp(argv[i],"--input") == 0 || strcmp(argv[i],"-input") == 0 || strcmp(argv[i],"-i") == 0 || strcmp(argv[i],"-in") == 0 ) { i++; file_name_in = argv[i]; } else if ( strcmp(argv[i],"--output") == 0 || strcmp(argv[i],"--out") == 0 || strcmp(argv[i],"-out") == 0 || strcmp(argv[i],"-o") == 0 ) { i++; file_name_out = argv[i]; } else if (file_name_in == 0 && file_name_out == 0) { file_name_in = argv[i]; } else if (file_name_in && file_name_out == 0) { file_name_out = argv[i]; } else { fprintf(stderr, "ERROR: unknown argument '%s'\n",argv[i]); usage(); exit(1); } } /* end looping through argc/argv */ num_entries = strlen(parse_string); if (use_stdout == TRUE && file_name_out){ LASError_Print("If an output file is specified, --stdout must not be used!"); exit(1); } reader = LASReader_Create(file_name_in); if (!reader) { LASError_Print("Unable to read file"); exit(1); } header = LASReader_GetHeader(reader); if (!header) { LASError_Print("Unable to fetch header for file"); exit(1); } if (use_stdout) { file_out = stdout; } else { if (file_name_out == NULL) { if (file_name_in == NULL) { LASError_Print("No input filename was specified"); usage(); exit(1); } len = (int)strlen(file_name_in); file_name_out = LASCopyString(file_name_in); if (file_name_out[len-3] == '.' && file_name_out[len-2] == 'g' && file_name_out[len-1] == 'z') { len = len - 4; } while (len > 0 && file_name_out[len] != '.') { len--; } file_name_out[len] = '\0'; } file_out = fopen(file_name_out, "wb"); } if (file_out == 0) { LASError_Print("Could not open file for write"); usage(); exit(1); } if (verbose) { print_header(stderr, header, file_name_in); } // Compute factors to add to X and Y and check sanity of generated codes double file_scale_x = LASHeader_GetScaleX(header); double file_scale_y = LASHeader_GetScaleY(header); if (check) { // Check specified scales are like in the LAS file if (fabs(scale_x - file_scale_x) > TOLERANCE){ fprintf(stderr, "ERROR: x scale in input file (%lf) does not match specified x scale (%lf)\n",file_scale_x, scale_x); exit(1); } if (fabs(scale_y - file_scale_y) > TOLERANCE){ fprintf(stderr, "ERROR: y scale in input file (%lf) does not match specified y scale (%lf)\n",file_scale_y, scale_y); exit(1); } /* Check that the extent of the file (taking into account the global offset) * is within 0,2^31 */ double check_min_x = 1.0 + LASHeader_GetMinX(header) - (((double) global_offset_x) * scale_x); if (check_min_x < TOLERANCE) { fprintf(stderr, "ERROR: Specied X global offset is too large. (MinX - (GlobalX*ScaleX)) < 0\n"); exit(1); } double check_min_y = 1.0 + LASHeader_GetMinY(header) - (((double) global_offset_y) * scale_y); if (check_min_y < TOLERANCE) { fprintf(stderr, "ERROR: Specied Y global offset is too large. (MinY - (GlobalY*ScaleY)) < 0\n"); exit(1); } double check_max_x = LASHeader_GetMaxX(header) - (((double) global_offset_x) * scale_x); if (check_max_x > (MAX_INT_31 * scale_x)) { fprintf(stderr, "ERROR: Specied X global offset is too small. (MaxX - (GlobalX*ScaleX)) > (2^31)*ScaleX\n"); exit(1); } double check_max_y = LASHeader_GetMaxY(header) - (((double) global_offset_y) * scale_y); if (check_max_y > (MAX_INT_31 * scale_y)) { fprintf(stderr, "ERROR: Specied Y global offset is too small. (MaxY - (GlobalY*ScaleY)) > (2^31)*ScaleY\n"); exit(1); } } /*Write Postgres header*/ struct postHeader pgHeader; pgHeader.s = "PGCOPY\n\377\r\n\0"; int i1T = 0, i2T = 0; pgHeader.i1 = htonl(i1T); pgHeader.i2 = htonl(i2T); fwrite(pgHeader.s, 11, 1, file_out); fwrite(&pgHeader.i1, sizeof(uint32_t), 1, file_out); fwrite(&pgHeader.i2, sizeof(uint32_t), 1, file_out); /* declaration for morton*/ uint32_t rawx = 0; uint32_t rawy = 0; uint64_t mortonkey = 0; /* scaled offsets to add for the morton encoding */ int64_t factorX = ((int64_t) (LASHeader_GetOffsetX(header) / file_scale_x)) - global_offset_x; int64_t factorY = ((int64_t) (LASHeader_GetOffsetY(header) / file_scale_y)) - global_offset_y; p = LASReader_GetNextPoint(reader); while (p) { if (skip_invalid && !LASPoint_IsValid(p)) { if (verbose) { LASError_Print("Skipping writing invalid point..."); } p = LASReader_GetNextPoint(reader); index -=1; continue; } struct postRow pgRow; uint32_t size; uint16_t hT = num_entries; pgRow.h = htons(hT); fwrite(& pgRow.h, 2, 1, file_out); size = sizeof(double); pgRow.vardSize = htonl(size); size = sizeof(uint32_t); pgRow.varSize = htonl(size); i = 0; for (;;) { LASColorH color = LASPoint_GetColor(p); double vard; int var; unsigned long long int vardL, varL; switch (parse_string[i]) { /* // the morton code on xy */ case 'k': rawx = (uint32_t) (((int64_t) LASPoint_GetRawX(p)) + factorX); rawy = (uint32_t) (((int64_t) LASPoint_GetRawY(p)) + factorY); mortonkey = EncodeMorton2D(rawx,rawy); varL = htobe64(mortonkey); fwrite(&pgRow.vardSize, sizeof(uint32_t), 1, file_out); fwrite(&varL, sizeof(uint64_t), 1, file_out); break; /* // the x coordinate */ case 'x': vard = LASPoint_GetX(p); fwrite(&pgRow.vardSize, sizeof(uint32_t), 1, file_out); vardL = bigEndian_double(vard); fwrite(&vardL, sizeof(double), 1, file_out); break; /* // the y coordinate */ case 'y': vard = LASPoint_GetY(p); fwrite(&pgRow.vardSize, sizeof(uint32_t), 1, file_out); vardL = bigEndian_double(vard); fwrite(&vardL, sizeof(double), 1, file_out); break; /* // the z coordinate */ case 'z': vard = LASPoint_GetZ(p); fwrite(&pgRow.vardSize, sizeof(uint32_t), 1, file_out); vardL = bigEndian_double(vard); fwrite(&vardL, sizeof(double), 1, file_out); break; /* // the gps-time */ case 't': vard = LASPoint_GetTime(p); fwrite(&pgRow.vardSize, sizeof(uint32_t), 1, file_out); vardL = bigEndian_double(vard); fwrite(&vardL, sizeof(double), 1, file_out); break; /* // the intensity */ case 'i': var = LASPoint_GetIntensity(p); fwrite(&pgRow.varSize, sizeof(uint32_t), 1, file_out); varL = htonl(var); fwrite(&varL, sizeof(uint32_t), 1, file_out); break; /* the scan angle */ case 'a': var = LASPoint_GetScanAngleRank(p); fwrite(&pgRow.varSize, sizeof(uint32_t), 1, file_out); varL = htonl(var); fwrite(&varL, sizeof(uint32_t), 1, file_out); break; /* the number of the return */ case 'r': var = LASPoint_GetReturnNumber(p); fwrite(&pgRow.varSize, sizeof(uint32_t), 1, file_out); varL = htonl(var); fwrite(&varL, sizeof(uint32_t), 1, file_out); break; /* the classification */ case 'c': var = LASPoint_GetClassification(p); fwrite(&pgRow.varSize, sizeof(uint32_t), 1, file_out); varL = htonl(var); fwrite(&varL, sizeof(uint32_t), 1, file_out); break; /* the user data */ case 'u': var = LASPoint_GetUserData(p); fwrite(&pgRow.varSize, sizeof(uint32_t), 1, file_out); varL = htonl(var); fwrite(&varL, sizeof(uint32_t), 1, file_out); break; /* the number of returns of given pulse */ case 'n': var = LASPoint_GetNumberOfReturns(p); fwrite(&pgRow.varSize, sizeof(uint32_t), 1, file_out); varL = htonl(var); fwrite(&varL, sizeof(uint32_t), 1, file_out); break; /* the red channel color */ case 'R': var = LASColor_GetRed(color); fwrite(&pgRow.varSize, sizeof(uint32_t), 1, file_out); varL = htonl(var); fwrite(&varL, sizeof(uint32_t), 1, file_out); break; /* the green channel color */ case 'G': var = LASColor_GetGreen(color); fwrite(&pgRow.varSize, sizeof(uint32_t), 1, file_out); varL = htonl(var); fwrite(&varL, sizeof(uint32_t), 1, file_out); break; /* the blue channel color */ case 'B': var = LASColor_GetBlue(color); fwrite(&pgRow.varSize, sizeof(uint32_t), 1, file_out); varL = htonl(var); fwrite(&varL, sizeof(uint32_t), 1, file_out); break; case 'M': var = index; fwrite(&pgRow.varSize, sizeof(uint32_t), 1, file_out); varL = htonl(var); fwrite(&varL, sizeof(uint32_t), 1, file_out); break; case 'p': var = LASPoint_GetPointSourceId(p); fwrite(&pgRow.varSize, sizeof(uint32_t), 1, file_out); varL = htonl(var); fwrite(&varL, sizeof(uint32_t), 1, file_out); break; /* the edge of flight line flag */ case 'e': var = LASPoint_GetFlightLineEdge(p); fwrite(&pgRow.varSize, sizeof(uint32_t), 1, file_out); varL = htonl(var); fwrite(&varL, sizeof(uint32_t), 1, file_out); break; /* the direction of scan flag */ case 'd': var = LASPoint_GetScanDirection(p); fwrite(&pgRow.varSize, sizeof(uint32_t), 1, file_out); varL = htonl(var); fwrite(&varL, sizeof(uint32_t), 1, file_out); break; } i++; if (!parse_string[i]) { break; } LASColor_Destroy(color); } p = LASReader_GetNextPoint(reader); index +=1; } short endT = -1; short end = htons(endT); fwrite(&end, sizeof(end), 1, file_out); fflush(file_out); fclose(file_out); LASReader_Destroy(reader); LASHeader_Destroy(header); return 0; }