void cap_http::parse_client_data(char content[], int number,char saddr[],char daddr[], unsigned short sport,unsigned short dport) { struct clientInfo* client=0; interaction* intern=0; TimeOut_Handler *th=0; char temp[MAX_BUFF_SIZE]={0}; int i=0; int k=0; int j=0; char entity_content[MAX_BUFF_SIZE]={0}; int chunkflag=0; int complete=0; unsigned int contentSize=0; unsigned int currentSize=0; char* seg=0; char resCode[RESPONSECODE_BUF_SIZE]={0}; char date[DATE_BUF_SIZE]={0}; char responseID[RESPONSEID_BUF_SIZE]={0}; char contentType[CONTENTTYPE_BUF_SIZE]={0}; int continued=0; int writeLen=0; int extract_chunk_ret=0; intern=_interactons.get_matched_interaction_m(saddr,daddr,sport); if (!intern) { cout <<"can't find matched interaction"<<endl; return; } if (intern->get_interaction_status()!=INTERACTION_NORMAL) { cout <<"current interaction time out"<<endl; return ; } intern->get_timeout_handler()->cancel_timer(); client=intern->get_client_info(); //set filter //set filter if (!client) { return; } //----------------------------------------------------------- if (number<4) { writeLen=my_min(number,MAX_BUFF_SIZE-1); memcpy(entity_content,content,writeLen); continued=1; } if (number>=4) { if(content[0] != 'H' && content[1] != 'T' && content[2] != 'T' && content[3] != 'P') //entity continued.... { writeLen=my_min(number,MAX_BUFF_SIZE-1); memcpy(entity_content,content,writeLen); continued=1; } else if (content[0] == 'H' && content[1] == 'T' && content[2] == 'T' && content[3] == 'P') { for (i=0;i<number;i++) { if ((i+1)<number) { if (content[i]=='\r'&&content[i+1]=='\n') { memset(temp,0,sizeof(temp)); memcpy(temp,content+i-k,my_min(k,MAX_BUFF_SIZE-1)); k=0; //temp operation if (strstr(temp,"HTTP")) { strncpy(resCode,temp,my_min(strlen(temp),RESPONSECODE_BUF_SIZE)); if (my_uuid_generate(responseID,64)!=0) { cout <<"response uuid generate failed"<<endl; } } if (strstr(temp, "Date")) { seg=(temp+strlen("Date: ")); strncpy(date,seg,my_min(strlen(seg),DATE_BUF_SIZE-1)); } if (strstr(temp, "Content-Length")) { seg=(temp+strlen("Content-Length: ")); contentSize=strtol(seg,NULL,10); //取得content-length if (contentSize==0) { complete=1; } else { if (contentSize>MAX_BUFF_SIZE) { contentSize=MAX_BUFF_SIZE; } } } if (strstr(temp, "Content-Type")) { seg=(temp+strlen("Content-Type: ")); strncpy(contentType,seg,my_min(strlen(seg),CONTENTTYPE_BUF_SIZE-1)); } if (strstr(temp, "Transfer-Encoding")) { seg=(temp+strlen("Transfer-Encoding: ")); if (strstr(seg,"chunked")) { chunkflag=1; } } //temp operation end if ((i+3)<number) { if (content[i]=='\r'&&content[i+1]=='\n'&&content[i+2]=='\r'&&content[i+3]=='\n') //content { if (number==i+4) { //printf("no content \n"); //no content break; } writeLen=my_min(number-i-4,MAX_BUFF_SIZE-1); memcpy(entity_content,content+i+4,writeLen); break; } } i+=1; } else { ++k; continue; } } } } } //lock //将内容写到链表的clientinfo中 { if (!continued) { if (chunkflag) { _interactons.set_matched_client_isChunked(client,1); } else { _interactons.malloc_matched_client_content(client,contentSize); _interactons.set_matched_client_isComplete(client,complete); } _interactons.set_matched_client_new_sip_info(client,intern->get_server_info()->requestID ,responseID,contentType,resCode,date); } _interactons.set_matched_client_chunked_content(client,entity_content,writeLen); _interactons.set_matched_client_not_chunked_content(client,entity_content,writeLen); } //unlock }
// This function is called each time the DSP receives a new picture void userProcessColorImageFunc_laser(bgr *ptrImage) { int i; if (ptrImage != NULL) { // Initialize all arrays for equivalency for (i=0; i < MAX_NUM_EQUIVALENCIES; i++) { equivalency_objects[i] = 0; // initialze link array object_stats[i].num_pixels_in_object = 0; object_stats[i].sum_r = 0; object_stats[i].sum_c = 0; } num_unique_objects = 0; object_detected = 0; // First Pass thru image. Convert RGB to HSV. This code is taking into account that the robot's camera only returns // a value between 16 and 240 for pixel intensity. It also adds a gain of 2 to the blue intensity. for (r=0;r<IMAGE_ROWS;r++) { for(c=0;c<IMAGE_COLUMNS;c++) { red = ((ptrImage[r*IMAGE_COLUMNS+c].red - 16)*255)/224; green = ((ptrImage[r*IMAGE_COLUMNS+c].green - 16)*255)/224; blue = ptrImage[r*IMAGE_COLUMNS+c].blue*2; if (blue > 240) { blue = 240; } blue = ((blue - 16)*255)/224; min = my_min( red, green, blue ); value = my_max( red, green, blue ); delta = value - min; if( value != 0 ) { sat = (delta*255) / value; // s if (delta != 0) { if( red == value ) hue = 60*( green - blue ) / delta; // between yellow & magenta else if( green == value ) hue = 120 + 60*( blue - red ) / delta; // between cyan & yellow else hue = 240 + 60*( red - green ) / delta; // between magenta & cyan if( hue < 0 ) hue += 360; } else { hue = 0; sat = 0; } } else { // r = g = b = 0 // s = 0, v is undefined sat = 0; hue = 0; } hue = (hue*255)/360; if ( (abs(sat-specs_s)<=specs_srad) && (abs(value-specs_v)<=specs_vrad) && ( (abs(hue-specs_h)<=specs_hrad) || (abs(hue-specs_h2)<=specs_hrad) // catch the hue wraparround ) ) { object_detected = 1; // Set a flag that at least one pixel found above threshold // -------- Connectivity calculations ------------ // Labels pixels 1 to MAX_NUM_EQUIVALENCIES depending on top and left neighbors // The labels represent object number... if (r == 0) top = 0; else top = Thres_Image[(r-1)*IMAGE_COLUMNS+c]; // previous row, same column if (c == 0) left = 0; else left = Thres_Image[r*IMAGE_COLUMNS+(c-1)]; // same row, previous column neighbor_type = 0; if (left != 0) neighbor_type += 1; if (top != 0) neighbor_type += 2; current_object = 0; switch (neighbor_type) { case 0: // Both neighbors zero, New object needed if (num_unique_objects < (MAX_NUM_EQUIVALENCIES-1) ) { num_unique_objects++; equivalency_objects[num_unique_objects] = num_unique_objects; } else { too_many_objects++; } current_object = num_unique_objects; break; case 1: // Top is zero, left is not zero current_object = left; break; case 2: // Left is zero, top is not zero current_object = top; break; case 3: // Top and left are not zero... must note equivalency if (top == left) current_object = left; else { if (Check_Equivalency(top,left) == 0) { current_object = Set_Equivalency(top,left); } else { current_object = left; } } break; default: // Should NEVER enter here current_object = 0; // Object 0 stores errors break; } Thres_Image[r*IMAGE_COLUMNS+c] = current_object; object_stats[current_object].num_pixels_in_object +=1; object_stats[current_object].sum_r += r; object_stats[current_object].sum_c += c; // ---------- Done with connectivity calculations (first pass) ---------- } else { Thres_Image[r*IMAGE_COLUMNS+c] = 0; } } } // initialize final object stats for (i=1; i<= MAX_NUM_OBJECTS; i++) { final_object_stats[i].sum_r = 0; final_object_stats[i].sum_c = 0; final_object_stats[i].num_pixels_in_object = 0; final_object_stats[i].center_r = 0.0; final_object_stats[i].center_c = 0.0; final_object_stats[i].C02_sum = 0.0; final_object_stats[i].C11_sum = 0.0; final_object_stats[i].C20_sum = 0.0; final_object_stats[i].theta = 0.0; } if (object_detected == 0) { num_unique_objects = 0; } else { num_unique_objects = Fix_Equivalency(num_unique_objects);// num_unique_objects contains the number of initial equivalencies found } if (num_unique_objects > MAX_NUM_OBJECTS) num_unique_objects = MAX_NUM_OBJECTS; // Third pass: correct image for nice display and calculate object moments // This is commented out because for the 176X144 image this adds a large amount of proccessing time when a large blob is found // for (r=0; r < IMAGE_ROWS; r++) { // Loop over rows // for (c=0; c < IMAGE_COLUMNS; c++) { // Loop over columns // if (Thres_Image[r*IMAGE_COLUMNS+c] > 0) { // // Fix pixel equivalency // Thres_Image[r*IMAGE_COLUMNS+c] = equivalency_objects[Thres_Image[r*IMAGE_COLUMNS+c]]; // // // Calculate second moments here // if ((Thres_Image[r*IMAGE_COLUMNS+c] > 0) && (Thres_Image[r*IMAGE_COLUMNS+c] <= MAX_NUM_OBJECTS)) { // final_object_stats[Thres_Image[r*IMAGE_COLUMNS+c]].C02_sum += (c - final_object_stats[Thres_Image[r*IMAGE_COLUMNS+c]].center_c)*(c - final_object_stats[Thres_Image[r*IMAGE_COLUMNS+c]].center_c); // final_object_stats[Thres_Image[r*IMAGE_COLUMNS+c]].C11_sum += (r - final_object_stats[Thres_Image[r*IMAGE_COLUMNS+c]].center_r)*(c - final_object_stats[Thres_Image[r*IMAGE_COLUMNS+c]].center_c); // final_object_stats[Thres_Image[r*IMAGE_COLUMNS+c]].C20_sum += (r - final_object_stats[Thres_Image[r*IMAGE_COLUMNS+c]].center_r)*(r - final_object_stats[Thres_Image[r*IMAGE_COLUMNS+c]].center_r); // } // // } // } // } // Find largest object and calculate object orientation largest_num_pixels = 0; largest_object = 1; for (k = 1; k <= num_unique_objects ; k++) { if (final_object_stats[k].num_pixels_in_object > largest_num_pixels) { largest_num_pixels = final_object_stats[k].num_pixels_in_object; largest_object = k; } // find theta of found blob // commented out because moments need to be calculated above to use this code. // if (final_object_stats[k].num_pixels_in_object > NUMPIXELS_TO_CALC_ANGLE) { // // Calculate the object orientation angle if there are NUMPIXELS_TO_CALC_ANGLE in the object // Cdifference = final_object_stats[k].C20_sum - final_object_stats[k].C02_sum; // if (Cdifference != 0.0F) { // can't divide by zero // final_object_stats[k].theta = atansp(final_object_stats[k].C11_sum/Cdifference)/2.0F; // } else { // final_object_stats[k].theta = 0.0; // } // if (final_object_stats[k].C20_sum > final_object_stats[k].C02_sum) { // if (final_object_stats[k].theta < 0) final_object_stats[k].theta += PI/2.0F; // else final_object_stats[k].theta += -PI/2.0F; // } // } else { // final_object_stats[k].theta = 0; // } } // Ends loop through objects // Find the middle rbar = (int) (final_object_stats[largest_object].center_r); cbar = (int) (final_object_stats[largest_object].center_c); // pass data to RobotControl() if (new_coordata == 0) { if (final_object_stats[largest_object].num_pixels_in_object > 1) { noimagefound = 0; new_num_found_objects = num_unique_objects; object_x = cbar - IMAGE_COLUMNS/2; object_y = rbar - IMAGE_ROWS/2; numpels = final_object_stats[largest_object].num_pixels_in_object; //new_object_theta = final_object_stats[largest_object].theta; //new_C20 = final_object_stats[largest_object].C20_sum; //new_C02 = final_object_stats[largest_object].C02_sum; new_coordata = 1; } else { noimagefound = 1; new_num_found_objects = num_unique_objects; object_x = 0.0; object_y = 0.0; numpels = 0; //new_object_theta = 0.0; //new_C20 = 0.0; //new_C02 = 0.0; new_coordata = 1; } } //create green x for largest centroid position if (final_object_stats[largest_object].num_pixels_in_object > 6) { ptrImage[rbar*IMAGE_COLUMNS+cbar].red = 0; ptrImage[rbar*IMAGE_COLUMNS+cbar].blue = 0; ptrImage[rbar*IMAGE_COLUMNS+cbar].green = 255; if (rbar > 0) { ptrImage[(rbar-1)*IMAGE_COLUMNS+cbar].red = 0; ptrImage[(rbar-1)*IMAGE_COLUMNS+cbar].blue = 0; ptrImage[(rbar-1)*IMAGE_COLUMNS+cbar].green = 255; } if (rbar < (IMAGE_ROWS-1)) { ptrImage[(rbar+1)*IMAGE_COLUMNS+cbar].red = 0; ptrImage[(rbar+1)*IMAGE_COLUMNS+cbar].blue = 0; ptrImage[(rbar+1)*IMAGE_COLUMNS+cbar].green = 255; } if (cbar > 0) { ptrImage[rbar*IMAGE_COLUMNS+(cbar-1)].red = 0; ptrImage[rbar*IMAGE_COLUMNS+(cbar-1)].blue = 0; ptrImage[rbar*IMAGE_COLUMNS+(cbar-1)].green = 255; } if (cbar < (IMAGE_COLUMNS-1)) { ptrImage[rbar*IMAGE_COLUMNS+(cbar+1)].red = 0; ptrImage[rbar*IMAGE_COLUMNS+(cbar+1)].blue = 0; ptrImage[rbar*IMAGE_COLUMNS+(cbar+1)].green = 255; } } if ( 12 == switchstate) { UpdateLCDwithLADAR(ptrImage,1); } // Send image to Color LCD if LCD ready for new data if (updateLCD) { updateLCD = 0; BCACHE_inv((void *)(ADDR_VIDEO_DATA_BASE+0x1A900),IMAGE_ROWS*IMAGE_COLUMNS*3,EDMA3_CACHE_WAIT); // Flush or write back source BCACHE_wb ((void *)ptrImage,IMAGE_ROWS*IMAGE_COLUMNS*3,EDMA3_CACHE_WAIT); //Need to clean the cache here EDMA3_1_Regs->PARAMENTRY[33].OPT = 0x0011E00C; EDMA3_1_Regs->PARAMENTRY[33].SRC = (unsigned int)Image_data; EDMA3_1_Regs->PARAMENTRY[33].A_B_CNT = 0x004004A4; //Maybe to ACNT = 1188 and BCNT = 64 EDMA3_1_Regs->PARAMENTRY[33].DST = (ADDR_VIDEO_DATA_BASE+LCD_IMAGE_OFFSET); EDMA3_1_Regs->PARAMENTRY[33].SRC_DST_BIDX = 0x04A404A4; EDMA3_1_Regs->PARAMENTRY[33].LINK_BCNTRLD = 0x0000FFFF; // Null link EDMA3_1_Regs->PARAMENTRY[33].SRC_DST_CIDX = 0x0; EDMA3_1_Regs->PARAMENTRY[33].CCNT = 0x1; //Last command triggers transmission } // If Linux is ready for another full 176X144 RGB image start the EDMA transfer of the image to external memory if (GET_IMAGE_TO_LINUX) { // Invalidate Destination BCACHE_inv((void *)Linux_Image,IMAGE_ROWS*IMAGE_COLUMNS*3,EDMA3_CACHE_WAIT); // Flush or write back source BCACHE_wb ((void *)ptrImage,IMAGE_ROWS*IMAGE_COLUMNS*3,EDMA3_CACHE_WAIT); EDMA3_1_Regs->PARAMENTRY[32].OPT = 0x0011F00C; EDMA3_1_Regs->PARAMENTRY[32].SRC = (unsigned int)Image_data; EDMA3_1_Regs->PARAMENTRY[32].A_B_CNT = 0x004004A4; //Maybe to ACNT = 1188 and BCNT = 64 EDMA3_1_Regs->PARAMENTRY[32].DST = (ADDR_VIDEO_DATA_BASE+LINUX_IMAGE_OFFSET); EDMA3_1_Regs->PARAMENTRY[32].SRC_DST_BIDX = 0x04A404A4; EDMA3_1_Regs->PARAMENTRY[32].LINK_BCNTRLD = 0x0000FFFF; // Null link EDMA3_1_Regs->PARAMENTRY[32].SRC_DST_CIDX = 0x0; EDMA3_1_Regs->PARAMENTRY[32].CCNT = 0x1; //Last command triggers transmission } } // Ends if statement to see if image pointer is null }
void cap_http::parse_server_data(char content[], int number,char saddr[],char daddr[], unsigned short sport,unsigned short dport) { interaction* pinter=0; struct serverInfo* serinfo=0; char temp[MAX_BUFF_SIZE]={0}; char* seg={0}; int i=0; int k=0; int j=0; int entity_index=0; char entity_content[REQUEST_CONTENT_BUF_SIZE]={0}; int ret; int minSize=0; //------------------------------------------------- for (i=0;i<number;i++) { if ((i+1)<number) { if (content[i]=='\r'&&content[i+1]=='\n') { memset(temp,0,sizeof(temp)); memcpy(temp,content+i-k,my_min(k,MAX_BUFF_SIZE-1)); k=0; if (strstr(temp, "GET")||strstr(temp,"POST")) //方法暂时只取两种GET POST { ret=create_one_interaction(&pinter); if (ret==0) { init_request_interaction(pinter,temp,saddr,daddr,sport,dport); serinfo=pinter->get_server_info(); } else cout <<"create one interaction failed"<<endl; } if (strstr(temp, "Accept:")) { seg=(temp + strlen("Accept: ")); if (serinfo) { strncpy(serinfo->accept,seg,my_min(strlen(seg),ACCEPT_BUF_SIZE-1)); } } if (strstr(temp, "Referer")) { seg=(temp+strlen("Referer: ")); if (serinfo) { strncpy(serinfo->refer,seg,my_min(strlen(seg),REFERER_BUF_SIZE-1)); } } if (strstr(temp, "Accept-Encoding")) { // printf("Accept-Encoding is:%s\n", temp + strlen("Accept-Encoding:")); //gzip编码 需要解压 seg=(temp+strlen("Accept-Encoding: ")); if (serinfo) { strncpy(serinfo->accEncod,seg,my_min(strlen(seg),ACCEPTENCODE_BUF_SIZE-1)); } } if (strstr(temp, "User-Agent")) { seg=(temp + strlen("User-Agent: ")); if (serinfo) { strncpy(serinfo->userAgent,seg,my_min(strlen(seg),USERAGENT_BUF_SIZE-1)); } } if (strstr(temp, "Host")) { seg=(temp + strlen("Host: ")); if (serinfo) { strncpy(serinfo->host,seg,my_min(strlen(seg),HOST_BUF_SIZE-1)); replace_str(serinfo->url,serinfo->des,serinfo->host); } } if (strstr(temp, "Cookie")) { seg=(temp + strlen("Cookie: ")); if (serinfo) { strncpy(serinfo->cookie,seg,my_min(strlen(seg),COOKIE_BUF_SIZE-1)); } } //temp operation end if ((i+3)<number) //正文部分 { if (content[i]=='\r'&&content[i+1]=='\n'&&content[i+2]=='\r'&&content[i+3]=='\n') // { if (number==i+4) { //no content break; } memcpy(entity_content,content+i+4,minSize=my_min(number-i-4,REQUEST_CONTENT_BUF_SIZE-1)); if (serinfo) { memcpy(serinfo->content,entity_content,minSize); serinfo->cntSize+=minSize; } break; } } i+=1; } else { ++k; continue; } } } //---------------------------------------------- if (pinter) { _interactons.put(pinter); } else cout <<"here we can't push one interaction into interaction_list"<<endl; }
int main(int argc, char *argv[]) { int i = 0; int a = 5; int b = 10; double c = 10; int *ptr = NULL; void *vptr; //----------------------------------------------------------------------------------------------------------------------------------- // Makra printf("pi = %f \n", PI); // pouzijeme makro printf("mensi je %d \n", MIN(a,b)); // a takto se makro rozvine printf("mensi je %d \n", ((a) < (b) ? (a) : (b))); // volani fce my_min printf("mensi je %d \n", my_min(a,b)); // volani inline fce printf("mensi je %d \n", inline_min(a,b)); // i takto jde pouzit makro, jako alias fce putc('*', stdout); putchar('*'); myputchar('*'); printf("\n"); // pouziti nevhodneho makra HALF_FPRINTF(stderr) "!ahoj!", 35); // pouzit vhodnejsiho makra FULL_FPRINTF(stderr, "!nazdar!", 45); printf("\n"); // pouziti makra __FILE__ printf("Ahoj tady je: %s \n", __FILE__); printf("a volam z radku: %d \n", __LINE__); printf("a to prave dnes: %s \n", __DATE__); printf("Fiiiiio\n"); //----------------------------------------------------------------------------------------------------------------------------------- // pouziti assert // spusti se asserace, pokud kompilujeme v DEBUG modu, tj. je definovano DEBUG // v pripade rls modu se aserace neprovede // v ptr je NULL //print_int(ptr); // ted ptr ukazuje na 'a' a vse je OK ptr = &a; print_int(ptr); //----------------------------------------------------------------------------------------------------------------------------------- // a jeset trosku neco k ptr, genericke pointry vptr = &b; print_int(vptr); // warning nekompatibilni *int a *void print_int((int*) vptr); vptr = &c; print_double((double*) vptr); return 0; }
{ while (true) { // Wrap the dictionary if needed. if (coder->dict.pos == coder->dict.size) coder->dict.pos = 0; // Store the current dictionary position. It is needed to know // where to start copying to the out[] buffer. const size_t dict_start = coder->dict.pos; // Calculate how much we allow coder->lz.code() to decode. // It must not decode past the end of the dictionary // buffer, and we don't want it to decode more than is // actually needed to fill the out[] buffer. coder->dict.limit = coder->dict.pos + my_min(out_size - *out_pos, coder->dict.size - coder->dict.pos); // Call the coder->lz.code() to do the actual decoding. const lzma_ret ret = coder->lz.code( coder->lz.coder, &coder->dict, in, in_pos, in_size); // Copy the decoded data from the dictionary to the out[] // buffer. const size_t copy_size = coder->dict.pos - dict_start; assert(copy_size <= out_size - *out_pos); memcpy(out + *out_pos, coder->dict.buf + dict_start, copy_size); *out_pos += copy_size; // Reset the dictionary if so requested by coder->lz.code().
int zipfile_tool(int argc, const char *argv[]) { const char *pMode = NULL; FILE *pInfile = NULL, *pOutfile = NULL; uint infile_size = 0; int level = Z_BEST_COMPRESSION; z_stream stream; int p = 1; const char *pSrc_filename = NULL; const char *pDst_filename = NULL; long file_loc = 0; if(SystemFlags::VERBOSE_MODE_ENABLED) printf("miniz.c version: %s\n", MZ_VERSION); if (argc < 4) { if(SystemFlags::VERBOSE_MODE_ENABLED) { printf("Usage: example3 [options] [mode:c or d] infile outfile\n"); printf("\nModes:\n"); printf("c - Compresses file infile to a zlib stream in file outfile\n"); printf("d - Decompress zlib stream in file infile to file outfile\n"); printf("\nOptions:\n"); printf("-l[0-10] - Compression level, higher values are slower.\n"); } return EXIT_FAILURE; } while ((p < argc) && (argv[p][0] == '-')) { switch (argv[p][1]) { case 'l': { level = atoi(&argv[1][2]); if ((level < 0) || (level > 10)) { if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Invalid level!\n"); return EXIT_FAILURE; } break; } default: { if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Invalid option: %s\n", argv[p]); return EXIT_FAILURE; } } p++; } if ((argc - p) < 3) { if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Must specify mode, input filename, and output filename after options!\n"); return EXIT_FAILURE; } else if ((argc - p) > 3) { if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Too many filenames!\n"); return EXIT_FAILURE; } pMode = argv[p++]; if (!strchr("cCdD", pMode[0])) { if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Invalid mode!\n"); if(SystemFlags::VERBOSE_MODE_ENABLED) return EXIT_FAILURE; } pSrc_filename = argv[p++]; pDst_filename = argv[p++]; if(SystemFlags::VERBOSE_MODE_ENABLED)printf("Mode: %c, Level: %d\nInput File: \"%s\"\nOutput File: \"%s\"\n", pMode[0], level, pSrc_filename, pDst_filename); // Open input file. pInfile = fopen(pSrc_filename, "rb"); if (!pInfile) { if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Failed opening input file!\n"); return EXIT_FAILURE; } // Determine input file's size. fseek(pInfile, 0, SEEK_END); file_loc = ftell(pInfile); fseek(pInfile, 0, SEEK_SET); if ((file_loc < 0) || (file_loc > INT_MAX)) { // This is not a limitation of miniz or tinfl, but this example. printf("File is too large to be processed by this example.\n"); fclose(pInfile); return EXIT_FAILURE; } infile_size = (uint)file_loc; // Open output file. pOutfile = fopen(pDst_filename, "wb"); if (!pOutfile) { printf("Failed opening output file!\n"); fclose(pInfile); return EXIT_FAILURE; } if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Input file size: %u\n", infile_size); // Init the z_stream memset(&stream, 0, sizeof(stream)); stream.next_in = s_inbuf; stream.avail_in = 0; stream.next_out = s_outbuf; stream.avail_out = BUF_SIZE; if ((pMode[0] == 'c') || (pMode[0] == 'C')) { // Compression. uint infile_remaining = infile_size; if (deflateInit(&stream, level) != Z_OK) { if(SystemFlags::VERBOSE_MODE_ENABLED) printf("deflateInit() failed!\n"); if(pInfile) fclose(pInfile); if(pOutfile) fclose(pOutfile); return EXIT_FAILURE; } for ( ; ; ) { int status; if (!stream.avail_in) { // Input buffer is empty, so read more bytes from input file. uint n = my_min(BUF_SIZE, infile_remaining); if (fread(s_inbuf, 1, n, pInfile) != n) { if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Failed reading from input file!\n"); if(pInfile) fclose(pInfile); if(pOutfile) fclose(pOutfile); return EXIT_FAILURE; } stream.next_in = s_inbuf; stream.avail_in = n; infile_remaining -= n; //printf("Input bytes remaining: %u\n", infile_remaining); } status = deflate(&stream, infile_remaining ? Z_NO_FLUSH : Z_FINISH); if ((status == Z_STREAM_END) || (!stream.avail_out)) { // Output buffer is full, or compression is done, so write buffer to output file. uint n = BUF_SIZE - stream.avail_out; if (fwrite(s_outbuf, 1, n, pOutfile) != n) { if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Failed writing to output file!\n"); if(pInfile) fclose(pInfile); if(pOutfile) fclose(pOutfile); return EXIT_FAILURE; } stream.next_out = s_outbuf; stream.avail_out = BUF_SIZE; } if (status == Z_STREAM_END) { break; } else if (status != Z_OK) { if(SystemFlags::VERBOSE_MODE_ENABLED) printf("deflate() failed with status %i!\n", status); if(pInfile) fclose(pInfile); if(pOutfile) fclose(pOutfile); return EXIT_FAILURE; } } if (deflateEnd(&stream) != Z_OK) { if(SystemFlags::VERBOSE_MODE_ENABLED) printf("deflateEnd() failed!\n"); if(pInfile) fclose(pInfile); if(pOutfile) fclose(pOutfile); return EXIT_FAILURE; } } else if ((pMode[0] == 'd') || (pMode[0] == 'D')) { // Decompression. uint infile_remaining = infile_size; if (inflateInit(&stream)) { if(SystemFlags::VERBOSE_MODE_ENABLED) printf("inflateInit() failed!\n"); if(pInfile) fclose(pInfile); if(pOutfile) fclose(pOutfile); return EXIT_FAILURE; } for ( ; ; ) { int status; if (!stream.avail_in) { // Input buffer is empty, so read more bytes from input file. uint n = my_min(BUF_SIZE, infile_remaining); if (fread(s_inbuf, 1, n, pInfile) != n) { if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Failed reading from input file!\n"); if(pInfile) fclose(pInfile); if(pOutfile) fclose(pOutfile); return EXIT_FAILURE; } stream.next_in = s_inbuf; stream.avail_in = n; infile_remaining -= n; } status = inflate(&stream, Z_SYNC_FLUSH); if ((status == Z_STREAM_END) || (!stream.avail_out)) { // Output buffer is full, or decompression is done, so write buffer to output file. uint n = BUF_SIZE - stream.avail_out; if (fwrite(s_outbuf, 1, n, pOutfile) != n) { if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Failed writing to output file!\n"); if(pInfile) fclose(pInfile); if(pOutfile) fclose(pOutfile); return EXIT_FAILURE; } stream.next_out = s_outbuf; stream.avail_out = BUF_SIZE; } if (status == Z_STREAM_END) { break; } else if (status != Z_OK) { if(SystemFlags::VERBOSE_MODE_ENABLED) printf("inflate() failed with status %i!\n", status); if(pInfile) fclose(pInfile); if(pOutfile) fclose(pOutfile); return EXIT_FAILURE; } } if (inflateEnd(&stream) != Z_OK) { if(SystemFlags::VERBOSE_MODE_ENABLED) printf("inflateEnd() failed!\n"); if(pInfile) fclose(pInfile); if(pOutfile) fclose(pOutfile); return EXIT_FAILURE; } } else { if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Invalid mode!\n"); if(pInfile) fclose(pInfile); if(pOutfile) fclose(pOutfile); return EXIT_FAILURE; } fclose(pInfile); pInfile = 0; if (EOF == fclose(pOutfile)) { if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Failed writing to output file!\n"); return EXIT_FAILURE; } if(SystemFlags::VERBOSE_MODE_ENABLED) { printf("Total input bytes: %u\n", (mz_uint32)stream.total_in); printf("Total output bytes: %u\n", (mz_uint32)stream.total_out); printf("Success.\n"); } return EXIT_SUCCESS; }
return; } ////////// // Misc // ////////// extern size_t lzma_bufcpy(const uint8_t *restrict in, size_t *restrict in_pos, size_t in_size, uint8_t *restrict out, size_t *restrict out_pos, size_t out_size) { const size_t in_avail = in_size - *in_pos; const size_t out_avail = out_size - *out_pos; const size_t copy_size = my_min(in_avail, out_avail); memcpy(out + *out_pos, in + *in_pos, copy_size); *in_pos += copy_size; *out_pos += copy_size; return copy_size; } extern lzma_ret lzma_next_filter_init(lzma_next_coder *next, const lzma_allocator *allocator, const lzma_filter_info *filters) { lzma_next_coder_init(filters[0].init, next, allocator);
int main(int argc, char *argv[]) { const char *pMode; FILE *pInfile, *pOutfile; uint infile_size; int level = 9; int p = 1; const char *pSrc_filename; const char *pDst_filename; const void *next_in = s_inbuf; size_t avail_in = 0; void *next_out = s_outbuf; size_t avail_out = OUT_BUF_SIZE; size_t total_in = 0, total_out = 0; long file_loc; assert(COMP_OUT_BUF_SIZE <= OUT_BUF_SIZE); printf("miniz.c example5 (demonstrates tinfl/tdefl)\n"); if (argc < 4) { printf("File to file compression/decompression using the low-level tinfl/tdefl API's.\n"); printf("Usage: example5 [options] [mode:c or d] infile outfile\n"); printf("\nModes:\n"); printf("c - Compresses file infile to a zlib stream in file outfile\n"); printf("d - Decompress zlib stream in file infile to file outfile\n"); printf("\nOptions:\n"); printf("-l[0-10] - Compression level, higher values are slower, 0 is none.\n"); return EXIT_FAILURE; } while ((p < argc) && (argv[p][0] == '-')) { switch (argv[p][1]) { case 'l': { level = atoi(&argv[1][2]); if ((level < 0) || (level > 10)) { printf("Invalid level!\n"); return EXIT_FAILURE; } break; } default: { printf("Invalid option: %s\n", argv[p]); return EXIT_FAILURE; } } p++; } if ((argc - p) < 3) { printf("Must specify mode, input filename, and output filename after options!\n"); return EXIT_FAILURE; } else if ((argc - p) > 3) { printf("Too many filenames!\n"); return EXIT_FAILURE; } pMode = argv[p++]; if (!strchr("cCdD", pMode[0])) { printf("Invalid mode!\n"); return EXIT_FAILURE; } pSrc_filename = argv[p++]; pDst_filename = argv[p++]; printf("Mode: %c, Level: %u\nInput File: \"%s\"\nOutput File: \"%s\"\n", pMode[0], level, pSrc_filename, pDst_filename); // Open input file. pInfile = fopen(pSrc_filename, "rb"); if (!pInfile) { printf("Failed opening input file!\n"); return EXIT_FAILURE; } // Determine input file's size. fseek(pInfile, 0, SEEK_END); file_loc = ftell(pInfile); fseek(pInfile, 0, SEEK_SET); if ((file_loc < 0) || (file_loc > INT_MAX)) { // This is not a limitation of miniz or tinfl, but this example. printf("File is too large to be processed by this example.\n"); return EXIT_FAILURE; } infile_size = (uint)file_loc; // Open output file. pOutfile = fopen(pDst_filename, "wb"); if (!pOutfile) { printf("Failed opening output file!\n"); return EXIT_FAILURE; } printf("Input file size: %u\n", infile_size); if ((pMode[0] == 'c') || (pMode[0] == 'C')) { // The number of dictionary probes to use at each compression level (0-10). 0=implies fastest/minimal possible probing. static const mz_uint s_tdefl_num_probes[11] = { 0, 1, 6, 32, 16, 32, 128, 256, 512, 768, 1500 }; tdefl_status status; uint infile_remaining = infile_size; // create tdefl() compatible flags (we have to compose the low-level flags ourselves, or use tdefl_create_comp_flags_from_zip_params() but that means MINIZ_NO_ZLIB_APIS can't be defined). mz_uint comp_flags = TDEFL_WRITE_ZLIB_HEADER | s_tdefl_num_probes[MZ_MIN(10, level)] | ((level <= 3) ? TDEFL_GREEDY_PARSING_FLAG : 0); if (!level) comp_flags |= TDEFL_FORCE_ALL_RAW_BLOCKS; // Initialize the low-level compressor. status = tdefl_init(&g_deflator, NULL, NULL, comp_flags); if (status != TDEFL_STATUS_OKAY) { printf("tdefl_init() failed!\n"); return EXIT_FAILURE; } avail_out = COMP_OUT_BUF_SIZE; // Compression. for ( ; ; ) { size_t in_bytes, out_bytes; if (!avail_in) { // Input buffer is empty, so read more bytes from input file. uint n = my_min(IN_BUF_SIZE, infile_remaining); if (fread(s_inbuf, 1, n, pInfile) != n) { printf("Failed reading from input file!\n"); return EXIT_FAILURE; } next_in = s_inbuf; avail_in = n; infile_remaining -= n; //printf("Input bytes remaining: %u\n", infile_remaining); } in_bytes = avail_in; out_bytes = avail_out; // Compress as much of the input as possible (or all of it) to the output buffer. status = tdefl_compress(&g_deflator, next_in, &in_bytes, next_out, &out_bytes, infile_remaining ? TDEFL_NO_FLUSH : TDEFL_FINISH); next_in = (const char *)next_in + in_bytes; avail_in -= in_bytes; total_in += in_bytes; next_out = (char *)next_out + out_bytes; avail_out -= out_bytes; total_out += out_bytes; if ((status != TDEFL_STATUS_OKAY) || (!avail_out)) { // Output buffer is full, or compression is done or failed, so write buffer to output file. uint n = COMP_OUT_BUF_SIZE - (uint)avail_out; if (fwrite(s_outbuf, 1, n, pOutfile) != n) { printf("Failed writing to output file!\n"); return EXIT_FAILURE; } next_out = s_outbuf; avail_out = COMP_OUT_BUF_SIZE; } if (status == TDEFL_STATUS_DONE) { // Compression completed successfully. break; } else if (status != TDEFL_STATUS_OKAY) { // Compression somehow failed. printf("tdefl_compress() failed with status %i!\n", status); return EXIT_FAILURE; } } } else if ((pMode[0] == 'd') || (pMode[0] == 'D')) { // Decompression. uint infile_remaining = infile_size; tinfl_decompressor inflator; tinfl_init(&inflator); for ( ; ; ) { size_t in_bytes, out_bytes; tinfl_status status; if (!avail_in) { // Input buffer is empty, so read more bytes from input file. uint n = my_min(IN_BUF_SIZE, infile_remaining); if (fread(s_inbuf, 1, n, pInfile) != n) { printf("Failed reading from input file!\n"); return EXIT_FAILURE; } next_in = s_inbuf; avail_in = n; infile_remaining -= n; } in_bytes = avail_in; out_bytes = avail_out; status = tinfl_decompress(&inflator, (const mz_uint8 *)next_in, &in_bytes, s_outbuf, (mz_uint8 *)next_out, &out_bytes, (infile_remaining ? TINFL_FLAG_HAS_MORE_INPUT : 0) | TINFL_FLAG_PARSE_ZLIB_HEADER); avail_in -= in_bytes; next_in = (const mz_uint8 *)next_in + in_bytes; total_in += in_bytes; avail_out -= out_bytes; next_out = (mz_uint8 *)next_out + out_bytes; total_out += out_bytes; if ((status <= TINFL_STATUS_DONE) || (!avail_out)) { // Output buffer is full, or decompression is done, so write buffer to output file. uint n = OUT_BUF_SIZE - (uint)avail_out; if (fwrite(s_outbuf, 1, n, pOutfile) != n) { printf("Failed writing to output file!\n"); return EXIT_FAILURE; } next_out = s_outbuf; avail_out = OUT_BUF_SIZE; } // If status is <= TINFL_STATUS_DONE then either decompression is done or something went wrong. if (status <= TINFL_STATUS_DONE) { if (status == TINFL_STATUS_DONE) { // Decompression completed successfully. break; } else { // Decompression failed. printf("tinfl_decompress() failed with status %i!\n", status); return EXIT_FAILURE; } } } } else { printf("Invalid mode!\n"); return EXIT_FAILURE; } fclose(pInfile); if (EOF == fclose(pOutfile)) { printf("Failed writing to output file!\n"); return EXIT_FAILURE; } printf("Total input bytes: %u\n", (mz_uint32)total_in); printf("Total output bytes: %u\n", (mz_uint32)total_out); printf("Success.\n"); return EXIT_SUCCESS; }
static void parse_environment(args_info *args, char *argv0, const char *varname) { char *env = getenv(varname); if (env == NULL) return; // We modify the string, so make a copy of it. env = xstrdup(env); // Calculate the number of arguments in env. argc stats at one // to include space for the program name. int argc = 1; bool prev_was_space = true; for (size_t i = 0; env[i] != '\0'; ++i) { // NOTE: Cast to unsigned char is needed so that correct // value gets passed to isspace(), which expects // unsigned char cast to int. Casting to int is done // automatically due to integer promotion, but we need to // force char to unsigned char manually. Otherwise 8-bit // characters would get promoted to wrong value if // char is signed. if (isspace((unsigned char)env[i])) { prev_was_space = true; } else if (prev_was_space) { prev_was_space = false; // Keep argc small enough to fit into a singed int // and to keep it usable for memory allocation. if (++argc == my_min( INT_MAX, SIZE_MAX / sizeof(char *))) message_fatal(_("The environment variable " "%s contains too many " "arguments"), varname); } } // Allocate memory to hold pointers to the arguments. Add one to get // space for the terminating NULL (if some systems happen to need it). char **argv = xmalloc(((size_t)(argc) + 1) * sizeof(char *)); argv[0] = argv0; argv[argc] = NULL; // Go through the string again. Split the arguments using '\0' // characters and add pointers to the resulting strings to argv. argc = 1; prev_was_space = true; for (size_t i = 0; env[i] != '\0'; ++i) { if (isspace((unsigned char)env[i])) { prev_was_space = true; env[i] = '\0'; } else if (prev_was_space) { prev_was_space = false; argv[argc++] = env + i; } } // Parse the argument list we got from the environment. All non-option // arguments i.e. filenames are ignored. parse_real(args, argc, argv); // Reset the state of the getopt_long() so that we can parse the // command line options too. There are two incompatible ways to // do it. #ifdef HAVE_OPTRESET // BSD optind = 1; optreset = 1; #else // GNU, Solaris optind = 0; #endif // We don't need the argument list from environment anymore. free(argv); free(env); return; }
int main (int argc, char *argv[]) { register struct nlist *s; register caddr_t strtab; register off_t stroff, symoff; register u_long symsize; register int cc; size_t strsize; struct nlist nbuf[1024]; struct exec exec; struct stat st; int fd; int pageOffset; if ((fd = open (argv[1], O_RDONLY)) < 0) { fprintf (stderr, "could not open %s\n", argv[1]); return -1; } if (lseek(fd, (off_t)0, SEEK_SET) == -1 || read(fd, &exec, sizeof(exec)) != sizeof(exec) || fstat(fd, &st) < 0) { fprintf (stderr, "Invalid binary file\n"); return -1; } if (N_BADMAG (exec) || N_GETMID (exec) != MID_I386) { fprintf (stderr, "invalid executable file N_BADMAG(exec) %d N_GETMID (exec) %d MID_I386 %d\n", N_BADMAG(exec), N_GETMID(exec), MID_I386); exit (1); } if (N_GETFLAG (exec) & EX_DYNAMIC) { fprintf (stderr, "are you giving me a dynamically linked executable??\n"); return -1; } symoff = N_SYMOFF(exec); symsize = exec.a_syms; stroff = symoff + symsize; #ifndef __linux__ /* Check for files too large to mmap. */ if (st.st_size - stroff > SIZE_T_MAX) { fprintf (stderr, "file too large\n"); return -1; } #endif /* * Map string table into our address space. This gives us * an easy way to randomly access all the strings, without * making the memory allocation permanent as with malloc/free * (i.e., munmap will return it to the system). */ strsize = st.st_size - stroff; pageOffset = stroff % 4096; stroff -= pageOffset; strsize += pageOffset; strtab = mmap(NULL, (size_t)strsize, PROT_READ, MAP_SHARED, fd, stroff); if (strtab == (char *)-1) { warn ("could not mmap string table"); return -1; } strtab += pageOffset; strsize -= pageOffset; if (lseek(fd, symoff, SEEK_SET) == -1) { fprintf (stderr, "could not lseek to symbol table\n"); return -1; } while (symsize > 0) { int i; cc = my_min(symsize, sizeof(nbuf)); if (read(fd, nbuf, cc) != cc) break; symsize -= cc; for (s = nbuf; cc > 0; ++s, cc -= sizeof(*s)) { register int soff = s->n_un.n_strx; if (soff == 0 || (s->n_type & N_STAB) != 0) continue; for (i = 0; exclude[i]; i++) { if (!strcmp (&strtab[soff], exclude[i])) goto skip; } /* hack to avoid symbol with name equal to tmp filename used to build us */ if (strchr (&strtab[soff], '.') || strchr (&strtab[soff], '/')) goto skip; if (s->n_type & N_EXT) { printf ("\t.globl\t%s\n\t.set\t%s,0x%lx\n\t.weak\t%s\n\n", &strtab[soff], &strtab[soff], s->n_value, &strtab[soff]); } skip: ; } } munmap(strtab, strsize); return 0; }
/// \brief Parse the Block Header /// /// The result is stored into *bhi. The caller takes care of initializing it. /// /// \return False on success, true on error. static bool parse_block_header(file_pair *pair, const lzma_index_iter *iter, block_header_info *bhi, xz_file_info *xfi) { #if IO_BUFFER_SIZE < LZMA_BLOCK_HEADER_SIZE_MAX # error IO_BUFFER_SIZE < LZMA_BLOCK_HEADER_SIZE_MAX #endif // Get the whole Block Header with one read, but don't read past // the end of the Block (or even its Check field). const uint32_t size = my_min(iter->block.total_size - lzma_check_size(iter->stream.flags->check), LZMA_BLOCK_HEADER_SIZE_MAX); io_buf buf; if (io_pread(pair, &buf, size, iter->block.compressed_file_offset)) return true; // Zero would mean Index Indicator and thus not a valid Block. if (buf.u8[0] == 0) goto data_error; lzma_block block; lzma_filter filters[LZMA_FILTERS_MAX + 1]; // Initialize the pointers so that they can be passed to free(). for (size_t i = 0; i < ARRAY_SIZE(filters); ++i) filters[i].options = NULL; // Initialize the block structure and decode Block Header Size. block.version = 0; block.check = iter->stream.flags->check; block.filters = filters; block.header_size = lzma_block_header_size_decode(buf.u8[0]); if (block.header_size > size) goto data_error; // Decode the Block Header. switch (lzma_block_header_decode(&block, NULL, buf.u8)) { case LZMA_OK: break; case LZMA_OPTIONS_ERROR: message_error("%s: %s", pair->src_name, message_strm(LZMA_OPTIONS_ERROR)); return true; case LZMA_DATA_ERROR: goto data_error; default: message_bug(); } // Check the Block Flags. These must be done before calling // lzma_block_compressed_size(), because it overwrites // block.compressed_size. bhi->flags[0] = block.compressed_size != LZMA_VLI_UNKNOWN ? 'c' : '-'; bhi->flags[1] = block.uncompressed_size != LZMA_VLI_UNKNOWN ? 'u' : '-'; bhi->flags[2] = '\0'; // Collect information if all Blocks have both Compressed Size // and Uncompressed Size fields. They can be useful e.g. for // multi-threaded decompression so it can be useful to know it. xfi->all_have_sizes &= block.compressed_size != LZMA_VLI_UNKNOWN && block.uncompressed_size != LZMA_VLI_UNKNOWN; // Validate or set block.compressed_size. switch (lzma_block_compressed_size(&block, iter->block.unpadded_size)) { case LZMA_OK: break; case LZMA_DATA_ERROR: goto data_error; default: message_bug(); } // Copy the known sizes. bhi->header_size = block.header_size; bhi->compressed_size = block.compressed_size; // Calculate the decoder memory usage and update the maximum // memory usage of this Block. bhi->memusage = lzma_raw_decoder_memusage(filters); if (xfi->memusage_max < bhi->memusage) xfi->memusage_max = bhi->memusage; // Convert the filter chain to human readable form. message_filters_to_str(bhi->filter_chain, filters, false); // Free the memory allocated by lzma_block_header_decode(). for (size_t i = 0; filters[i].id != LZMA_VLI_UNKNOWN; ++i) free(filters[i].options); return false; data_error: // Show the error message. message_error("%s: %s", pair->src_name, message_strm(LZMA_DATA_ERROR)); // Free the memory allocated by lzma_block_header_decode(). // This is truly needed only if we get here after a succcessful // call to lzma_block_header_decode() but it doesn't hurt to // always do it. for (size_t i = 0; filters[i].id != LZMA_VLI_UNKNOWN; ++i) free(filters[i].options); return true; }
/// \brief Parse the Index(es) from the given .xz file /// /// \param xfi Pointer to structure where the decoded information /// is stored. /// \param pair Input file /// /// \return On success, false is returned. On error, true is returned. /// // TODO: This function is pretty big. liblzma should have a function that // takes a callback function to parse the Index(es) from a .xz file to make // it easy for applications. static bool parse_indexes(xz_file_info *xfi, file_pair *pair) { if (pair->src_st.st_size <= 0) { message_error(_("%s: File is empty"), pair->src_name); return true; } if (pair->src_st.st_size < 2 * LZMA_STREAM_HEADER_SIZE) { message_error(_("%s: Too small to be a valid .xz file"), pair->src_name); return true; } io_buf buf; lzma_stream_flags header_flags; lzma_stream_flags footer_flags; lzma_ret ret; // lzma_stream for the Index decoder lzma_stream strm = LZMA_STREAM_INIT; // All Indexes decoded so far lzma_index *combined_index = NULL; // The Index currently being decoded lzma_index *this_index = NULL; // Current position in the file. We parse the file backwards so // initialize it to point to the end of the file. off_t pos = pair->src_st.st_size; // Each loop iteration decodes one Index. do { // Check that there is enough data left to contain at least // the Stream Header and Stream Footer. This check cannot // fail in the first pass of this loop. if (pos < 2 * LZMA_STREAM_HEADER_SIZE) { message_error("%s: %s", pair->src_name, message_strm(LZMA_DATA_ERROR)); goto error; } pos -= LZMA_STREAM_HEADER_SIZE; lzma_vli stream_padding = 0; // Locate the Stream Footer. There may be Stream Padding which // we must skip when reading backwards. while (true) { if (pos < LZMA_STREAM_HEADER_SIZE) { message_error("%s: %s", pair->src_name, message_strm( LZMA_DATA_ERROR)); goto error; } if (io_pread(pair, &buf, LZMA_STREAM_HEADER_SIZE, pos)) goto error; // Stream Padding is always a multiple of four bytes. int i = 2; if (buf.u32[i] != 0) break; // To avoid calling io_pread() for every four bytes // of Stream Padding, take advantage that we read // 12 bytes (LZMA_STREAM_HEADER_SIZE) already and // check them too before calling io_pread() again. do { stream_padding += 4; pos -= 4; --i; } while (i >= 0 && buf.u32[i] == 0); } // Decode the Stream Footer. ret = lzma_stream_footer_decode(&footer_flags, buf.u8); if (ret != LZMA_OK) { message_error("%s: %s", pair->src_name, message_strm(ret)); goto error; } // Check that the size of the Index field looks sane. lzma_vli index_size = footer_flags.backward_size; if ((lzma_vli)(pos) < index_size + LZMA_STREAM_HEADER_SIZE) { message_error("%s: %s", pair->src_name, message_strm(LZMA_DATA_ERROR)); goto error; } // Set pos to the beginning of the Index. pos -= index_size; // See how much memory we can use for decoding this Index. uint64_t memlimit = hardware_memlimit_get(MODE_LIST); uint64_t memused = 0; if (combined_index != NULL) { memused = lzma_index_memused(combined_index); if (memused > memlimit) message_bug(); memlimit -= memused; } // Decode the Index. ret = lzma_index_decoder(&strm, &this_index, memlimit); if (ret != LZMA_OK) { message_error("%s: %s", pair->src_name, message_strm(ret)); goto error; } do { // Don't give the decoder more input than the // Index size. strm.avail_in = my_min(IO_BUFFER_SIZE, index_size); if (io_pread(pair, &buf, strm.avail_in, pos)) goto error; pos += strm.avail_in; index_size -= strm.avail_in; strm.next_in = buf.u8; ret = lzma_code(&strm, LZMA_RUN); } while (ret == LZMA_OK); // If the decoding seems to be successful, check also that // the Index decoder consumed as much input as indicated // by the Backward Size field. if (ret == LZMA_STREAM_END) if (index_size != 0 || strm.avail_in != 0) ret = LZMA_DATA_ERROR; if (ret != LZMA_STREAM_END) { // LZMA_BUFFER_ERROR means that the Index decoder // would have liked more input than what the Index // size should be according to Stream Footer. // The message for LZMA_DATA_ERROR makes more // sense in that case. if (ret == LZMA_BUF_ERROR) ret = LZMA_DATA_ERROR; message_error("%s: %s", pair->src_name, message_strm(ret)); // If the error was too low memory usage limit, // show also how much memory would have been needed. if (ret == LZMA_MEMLIMIT_ERROR) { uint64_t needed = lzma_memusage(&strm); if (UINT64_MAX - needed < memused) needed = UINT64_MAX; else needed += memused; message_mem_needed(V_ERROR, needed); } goto error; } // Decode the Stream Header and check that its Stream Flags // match the Stream Footer. pos -= footer_flags.backward_size + LZMA_STREAM_HEADER_SIZE; if ((lzma_vli)(pos) < lzma_index_total_size(this_index)) { message_error("%s: %s", pair->src_name, message_strm(LZMA_DATA_ERROR)); goto error; } pos -= lzma_index_total_size(this_index); if (io_pread(pair, &buf, LZMA_STREAM_HEADER_SIZE, pos)) goto error; ret = lzma_stream_header_decode(&header_flags, buf.u8); if (ret != LZMA_OK) { message_error("%s: %s", pair->src_name, message_strm(ret)); goto error; } ret = lzma_stream_flags_compare(&header_flags, &footer_flags); if (ret != LZMA_OK) { message_error("%s: %s", pair->src_name, message_strm(ret)); goto error; } // Store the decoded Stream Flags into this_index. This is // needed so that we can print which Check is used in each // Stream. ret = lzma_index_stream_flags(this_index, &footer_flags); if (ret != LZMA_OK) message_bug(); // Store also the size of the Stream Padding field. It is // needed to show the offsets of the Streams correctly. ret = lzma_index_stream_padding(this_index, stream_padding); if (ret != LZMA_OK) message_bug(); if (combined_index != NULL) { // Append the earlier decoded Indexes // after this_index. ret = lzma_index_cat( this_index, combined_index, NULL); if (ret != LZMA_OK) { message_error("%s: %s", pair->src_name, message_strm(ret)); goto error; } } combined_index = this_index; this_index = NULL; xfi->stream_padding += stream_padding; } while (pos > 0); lzma_end(&strm); // All OK. Make combined_index available to the caller. xfi->idx = combined_index; return false; error: // Something went wrong, free the allocated memory. lzma_end(&strm); lzma_index_end(combined_index, NULL); lzma_index_end(this_index, NULL); return true; }
/* Actually save the PostScript data to the file stream: */ int do_ps_save(FILE * fi, // const char *restrict const fname, const char * fname, SDL_Surface * surf, char * pprsize, int is_pipe) { const struct paper * ppr; int img_w = surf->w; int img_h = surf->h; int r_img_w, r_img_h; int ppr_w, ppr_h; int x, y; float tlate_x, tlate_y; int cur_line_len; int plane; Uint8 r, g, b; char buf[256]; Uint32(*getpixel) (SDL_Surface *, int, int) = getpixels[surf->format->BytesPerPixel]; int printed_img_w, printed_img_h; time_t t = time(NULL); int rotate; float scale; /* Determine paper size: */ paperinit(); // FIXME: Should we do this at startup? -bjk 2007.06.25 if (pprsize == NULL) { /* User did not request a specific paper size (on command-line or in config file), ask the system. It will return either their $PAPER env. var., the value from /etc/papersize, or NULL: */ pprsize = (char *) systempapername(); if (pprsize == NULL) { /* No setting, env. var. or /etc/ file; use the default! */ pprsize = (char *) defaultpapername(); #ifdef DEBUG printf("Using default paper\n"); #endif } #ifdef DEBUG else { printf("Using system paper\n"); } #endif } #ifdef DEBUG else { printf("Using user paper\n"); } #endif #ifdef DEBUG printf("Using paper size: %s\n", pprsize); #endif /* Determine attributes of paper of the size chosen/determined: */ ppr = paperinfo(pprsize); ppr_w = paperpswidth(ppr); ppr_h = paperpsheight(ppr); #ifdef DEBUG printf("Paper is %d x %d (%.2f\" x %.2f\")\n", ppr_w, ppr_h, (float) ppr_w / 72.0, (float) ppr_h / 72.0); #endif paperdone(); // FIXME: Should we do this at quit? -bjk 2007.06.25 /* Determine whether it's best to rotate the image: */ if ((ppr_w >= ppr_h && img_w >= img_h) || (ppr_w <= ppr_h && img_w <= img_h)) { rotate = 0; r_img_w = img_w; r_img_h = img_h; } else { rotate = 1; r_img_w = img_h; r_img_h = img_w; } #ifdef DEBUG printf("Image is %d x %d\n", img_w, img_h); printf("Rotated? %s\n", rotate ? "yes" : "no"); printf("Will print %d x %d pixels\n", r_img_w, r_img_h); #endif /* Determine scale: */ scale = my_min(((float) (ppr_w - (MARGIN * 2)) / (float) r_img_w), ((float) (ppr_h - (MARGIN * 2)) / (float) r_img_h)); printed_img_w = r_img_w * scale; printed_img_h = r_img_h * scale; #ifdef DEBUG printf("Scaling image by %.2f (to %d x %d)\n", scale, printed_img_w, printed_img_h); #endif // FIXME - doesn't seem to center well -bjk 2007.06.25 tlate_x = (ppr_w - printed_img_w) / 2; tlate_y = (ppr_h - printed_img_h) / 2; /* Based off of output from "pnmtops", Tux Paint 0.9.15 thru 0.9.17 CVS as of June 2007, and Adobe Systems Incorporated's 'PostScript(r) Language Reference, 3rd Ed.' */ /* Begin PostScript output with some useful meta info in comments: */ fprintf(fi, "%%!PS-Adobe-2.0 EPSF-2.0\n"); // we need LanguageLevel2 for color fprintf(fi, "%%%%Title: (%s)\n", fname); strftime(buf, sizeof buf - 1, "%a %b %e %H:%M:%S %Y", localtime(&t)); fprintf(fi, "%%%%CreationDate: (%s)\n", buf); fprintf(fi, "%%%%Creator: (Tux Paint " VER_VERSION ", " VER_DATE ")\n"); fprintf(fi, "%%%%Pages: 1\n"); fprintf(fi, "%%%%BoundingBox: 0 0 %d %d\n", (int) (ppr_w + 0.5), (int) (ppr_h + 0.5)); fprintf(fi, "%%%%EndComments\n"); /* Define a 'readstring' routine and 'picstr' routines for RGB: */ fprintf(fi, "/readstring {\n"); fprintf(fi, " currentfile exch readhexstring pop\n"); fprintf(fi, "} bind def\n"); fprintf(fi, "/rpicstr %d string def\n", img_w); fprintf(fi, "/gpicstr %d string def\n", img_w); fprintf(fi, "/bpicstr %d string def\n", img_w); fprintf(fi, "%%%%EndProlog\n"); fprintf(fi, "%%%%Page: 1 1\n"); fprintf(fi, "<< /PageSize [ %d %d ] /ImagingBBox null >> setpagedevice\n", ppr_w, ppr_h); fprintf(fi, "gsave\n"); /* 'translate' moves the user space origin to a new position with respect to the current page, leaving the orientation of the axes and the unit lengths unchanged. */ fprintf(fi, "%d.%02d %d.%02d translate\n", f2int(tlate_x), f2dec(tlate_x), f2int(tlate_y), f2dec(tlate_y)); /* 'scale' modifies the unit lengths independently along the current x and y axes, leaving the origin location and the orientation of the axes unchanged. */ fprintf(fi, "%d.%02d %d.%02d scale\n", f2int(printed_img_w), f2dec(printed_img_w), f2int(printed_img_h), f2dec(printed_img_h)); /* Rotate the image */ if (rotate) fprintf(fi, "0.5 0.5 translate 90 rotate -0.5 -0.5 translate\n"); fprintf(fi, "%d %d 8\n", img_w, img_h); fprintf(fi, "[ %d 0 0 %d 0 %d ]\n", img_w, -img_h, img_h); fprintf(fi, "{ rpicstr readstring }\n"); fprintf(fi, "{ gpicstr readstring }\n"); fprintf(fi, "{ bpicstr readstring }\n"); fprintf(fi, "true 3\n"); fprintf(fi, "colorimage\n"); cur_line_len = 0; for (y = 0; y < img_h; y++) { for (plane = 0; plane < 3; plane++) { for (x = 0; x < img_w; x++) { SDL_GetRGB(getpixel(surf, x, y), surf->format, &r, &g, &b); fprintf(fi, "%02x", (plane == 0 ? r : (plane == 1 ? g : b))); cur_line_len++; if (cur_line_len >= 30) { fprintf(fi, "\n"); cur_line_len = 0; } } } } fprintf(fi, "\n"); fprintf(fi, "grestore\n"); fprintf(fi, "showpage\n"); fprintf(fi, "%%%%Trailer\n"); fprintf(fi, "%%%%EOF\n"); if (!is_pipe) { fclose(fi); return 1; } else { pid_t child_pid, w; int status; child_pid = pclose(fi); /* debug */ /* printf("pclose returned %d\n", child_pid); fflush(stdout); printf("errno = %d\n", errno); fflush(stdout); */ if (child_pid < 0 || (errno != 0 && errno != EAGAIN)) { /* FIXME: This right? */ return 0; } else if (child_pid == 0) { return 1; } do { w = waitpid(child_pid, &status, 0); /* debug */ /* if (w == -1) { perror("waitpid"); exit(EXIT_FAILURE); } if (WIFEXITED(status)) { printf("exited, status=%d\n", WEXITSTATUS(status)); } else if (WIFSIGNALED(status)) { printf("killed by signal %d\n", WTERMSIG(status)); } else if (WIFSTOPPED(status)) { printf("stopped by signal %d\n", WSTOPSIG(status)); } else if (WIFCONTINUED(status)) { printf("continued\n"); } */ } while (w != -1 && !WIFEXITED(status) && !WIFSIGNALED(status)); if (WIFEXITED(status) && WEXITSTATUS(status) != 0) /* Not happy exit */ return 0; return 1; } }
void alloc_and_load_rr_indexed_data (t_segment_inf *segment_inf, int num_segment, int **rr_node_indices, int nodes_per_chan, int wire_to_ipin_switch, enum e_base_cost_type base_cost_type) { /* Allocates the rr_indexed_data array and loads it with appropriate values. * * It currently stores the segment type (or OPEN if the index doesn't * * correspond to an CHANX or CHANY type), the base cost of nodes of that * * type, and some info to allow rapid estimates of time to get to a target * * to be computed by the router. */ /* Right now all SOURCES have the same base cost; and similarly there's only * * one base cost for each of SINKs, OPINs, and IPINs (four total). This can * * be changed just by allocating more space in the array below and changing * * the cost_index values for these rr_nodes, if you want to make some pins * * etc. more expensive than others. I give each segment type in an * * x-channel its own cost_index, and each segment type in a y-channel its * * own cost_index. */ int iseg, length, i, index; num_rr_indexed_data = CHANX_COST_INDEX_START + 2 * num_segment; rr_indexed_data = (t_rr_indexed_data *) my_malloc (num_rr_indexed_data * sizeof (t_rr_indexed_data)); /* For rr_types that aren't CHANX or CHANY, base_cost is valid, but most * * other fields are invalid. For IPINs, the T_linear field is also valid; * * all other fields are invalid. For SOURCES, SINKs and OPINs, all fields * * other than base_cost are invalid. Mark invalid fields as OPEN for safety. */ for (i=SOURCE_COST_INDEX;i<=IPIN_COST_INDEX;i++) { rr_indexed_data[i].ortho_cost_index = OPEN; rr_indexed_data[i].seg_index = OPEN; rr_indexed_data[i].inv_length = OPEN; rr_indexed_data[i].T_linear = OPEN; rr_indexed_data[i].T_quadratic = OPEN; rr_indexed_data[i].C_load = OPEN; } rr_indexed_data[IPIN_COST_INDEX].T_linear = switch_inf[wire_to_ipin_switch].Tdel; /* X-directed segments. */ for (iseg=0;iseg<num_segment;iseg++) { index = CHANX_COST_INDEX_START + iseg; rr_indexed_data[index].ortho_cost_index = index + num_segment; if (segment_inf[iseg].longline) length = nx; else length = my_min(segment_inf[iseg].length, nx); rr_indexed_data[index].inv_length = 1./length; rr_indexed_data[index].seg_index = iseg; } load_rr_indexed_data_T_values (CHANX_COST_INDEX_START, num_segment, CHANX, nodes_per_chan, rr_node_indices, segment_inf); /* Y-directed segments. */ for (iseg=0;iseg<num_segment;iseg++) { index = CHANX_COST_INDEX_START + num_segment + iseg; rr_indexed_data[index].ortho_cost_index = index - num_segment; if (segment_inf[iseg].longline) length = ny; else length = my_min(segment_inf[iseg].length, ny); rr_indexed_data[index].inv_length = 1./length; rr_indexed_data[index].seg_index = iseg; } load_rr_indexed_data_T_values (CHANX_COST_INDEX_START + num_segment, num_segment, CHANY, nodes_per_chan, rr_node_indices, segment_inf); load_rr_indexed_data_base_costs (nodes_per_chan, rr_node_indices, base_cost_type, wire_to_ipin_switch); }